This is code used to make plots based on output from the “IndividualPondModels_Forecasts85” for boththe CR and YF Read in the output files for each pond/RCP combination then work on delta figures and figures like Hamlet et al. 2020

rm(list = ls())

library(tidyverse)
library(dplyr)
library(rjags)
library(ggplot2)

set.seed(1)

Starting with the Yakutat Forelands

RCP 85

Reading in the data

Mod_YF85 <- read.csv("Mod_YF85.csv", header = T)

2012-2020

# List of unique pond names from the dataframe
pond_names <- unique(Mod_YF85$pond_name)

# Initialize an empty dataframe to store results
avgMed_2020 <- data.frame(Pond = pond_names, AvgMed_2020 = numeric(length(pond_names)))

# Loop through each pond name
for (i in seq_along(pond_names)) {
  pond_name <- pond_names[i]
  
  # Filter data for the current pond and for dates before January 1, 2021
  filtered_data <- Mod_YF85 %>%
    filter(pond_name == !!pond_name, as.Date(time) < as.Date("2021-01-01"))
  
  # Calculate the mean of 'med' (which corresponds to X50%)
  avg_med <- mean(filtered_data$med, na.rm = TRUE)
  
  # Store the result in the dataframe
  avgMed_2020[i, "AvgMed_2020"] <- avg_med
}

# Print the dataframe
print(avgMed_2020)

2030-2039

library(lubridate)
library(dplyr)
library(tidyr)
library(ggplot2)

# List of unique pond names from the dataframe
pond_names <- unique(Mod_YF85$pond_name)

# Initialize a dataframe to store results with years as columns
avgMed_2030 <- data.frame(Pond = pond_names)

# Loop through each year from 2030 to 2039
for (yr in 2030:2039) {
  # Calculate average medians for each year and store as a new column
  avgMed_col <- sapply(pond_names, function(pond_name) {
    yearly_data <- Mod_YF85 %>%
      filter(pond_name == !!pond_name, year(as.Date(time)) == yr)
    
    avg_med <- mean(yearly_data$med, na.rm = TRUE)
    return(avg_med)
  })
  
  # Add the results as a new column to the dataframe
  avgMed_2030[[as.character(yr)]] <- avgMed_col
}

# Print the final dataframe
print(avgMed_2030)

# Convert to long format for ggplot2
avgMed_2030_long <- avgMed_2030 %>%
  pivot_longer(cols = -Pond, names_to = "Year", values_to = "AvgMed")

# Plot the data
ggplot(avgMed_2030_long, aes(x = Year, y = AvgMed, color = Pond, group = Pond)) +
  geom_line() +
  geom_point() +
  labs(title = "Average Median per Pond from 2030 to 2039",
       x = "Year",
       y = "Average Median") +
  theme_minimal()

2060-2069

library(lubridate)
library(dplyr)
library(tidyr)
library(ggplot2)

# List of unique pond names from the dataframe
pond_names <- unique(Mod_YF85$pond_name)

# Initialize a dataframe to store results with years as columns
avgMed_2060 <- data.frame(Pond = pond_names)

# Loop through each year from 2060 to 2069
for (yr in 2060:2069) {
  # Calculate average medians for each year and store as a new column
  avgMed_col <- sapply(pond_names, function(pond_name) {
    yearly_data <- Mod_YF85 %>%
      filter(pond_name == !!pond_name, year(as.Date(time)) == yr)
    
    avg_med <- mean(yearly_data$med, na.rm = TRUE)
    return(avg_med)
  })
  
  # Add the results as a new column to the dataframe
  avgMed_2060[[as.character(yr)]] <- avgMed_col
}

# Print the final dataframe
print(avgMed_2060)

# Convert to long format for ggplot2
avgMed_2060_long <- avgMed_2060 %>%
  pivot_longer(cols = -Pond, names_to = "Year", values_to = "AvgMed")

# Plot the data
ggplot(avgMed_2060_long, aes(x = Year, y = AvgMed, color = Pond, group = Pond)) +
  geom_line() +
  geom_point() +
  labs(title = "Average Median per Pond from 2060 to 2069",
       x = "Year",
       y = "Average Median") +
  theme_minimal()

2090-2099

library(lubridate)
library(dplyr)
library(tidyr)
library(ggplot2)

# List of unique pond names from the dataframe
pond_names <- unique(Mod_YF85$pond_name)

# Initialize a dataframe to store results with years as columns
avgMed_2090 <- data.frame(Pond = pond_names)

# Loop through each year from 2090 to 2099
for (yr in 2090:2099) {
  # Calculate average medians for each year and store as a new column
  avgMed_col <- sapply(pond_names, function(pond_name) {
    yearly_data <- Mod_YF85 %>%
      filter(pond_name == !!pond_name, year(as.Date(time)) == yr)
    
    avg_med <- mean(yearly_data$med, na.rm = TRUE)
    return(avg_med)
  })
  
  # Add the results as a new column to the dataframe
  avgMed_2090[[as.character(yr)]] <- avgMed_col
}

# Print the final dataframe
print(avgMed_2090)

# Convert to long format for ggplot2
avgMed_2090_long <- avgMed_2090 %>%
  pivot_longer(cols = -Pond, names_to = "Year", values_to = "AvgMed")

# Plot the data
ggplot(avgMed_2090_long, aes(x = Year, y = AvgMed, color = Pond, group = Pond)) +
  geom_line() +
  geom_point() +
  labs(title = "Average Median per Pond from 2090 to 2099",
       x = "Year",
       y = "Average Median") +
  theme_minimal()

# Rename columns to reflect only the years
avgMed_2020 <- avgMed_2020 %>%
  rename(AvgMed_2020 = AvgMed_2020)

avgMed_2030 <- avgMed_2030 %>%
  rename(`2030` = `2030`)

avgMed_2060 <- avgMed_2060 %>%
  rename(`2060` = `2060`)

avgMed_2090 <- avgMed_2090 %>%
  rename(`2090` = `2090`)

# Combine the data frames
combined_avgMed <- avgMed_2020 %>%
  left_join(avgMed_2030, by = "Pond") %>%
  left_join(avgMed_2060, by = "Pond") %>%
  left_join(avgMed_2090, by = "Pond")

# Print the final dataframe
print(combined_avgMed)

# Convert to long format for ggplot2, excluding AvgMed_2020
avgMed_long <- combined_avgMed %>%
  pivot_longer(cols = -Pond, names_to = "Year", values_to = "AvgMed") %>%
  filter(Year %in% as.character(2021:2199))

# Plot the data
ggplot(avgMed_long, aes(x = Year, y = AvgMed, color = Pond, group = Pond)) +
  geom_line() +
  geom_point() +
  labs(title = "Average Median per Pond in the YF - RCP 8.5",
       x = "Year",
       y = "Average Median") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1),# Rotate x-axis labels by 45 degrees
        plot.title = element_text(hjust = 0.5))  

Calcuate the differences here as new columns in the dataframe

library(dplyr)

# Assuming combined_avgMed is loaded and structure verified
Delta_combined_avgMed <- combined_avgMed  # Use your actual dataframe

# Columns to calculate differences for
years <- c("2030", "2031", "2032", "2033", "2034", 
           "2035", "2036", "2037", "2038", "2039", 
           "2060", "2061", "2062", "2063", "2064", 
           "2065", "2066", "2067", "2068", "2069", 
           "2090", "2091", "2092", "2093", "2094", 
           "2095", "2096", "2097", "2098", "2099")

# Loop through each year and calculate the difference
for (year in years) {
  # Create a new column for the difference
  diff_col_name <- paste0("diff_", year)
  Delta_combined_avgMed[[diff_col_name]] <- Delta_combined_avgMed[[year]] - Delta_combined_avgMed$`AvgMed_2020`
}

# Display the structure of Delta_combined_avgMed to verify
str(Delta_combined_avgMed)
'data.frame':   11 obs. of  62 variables:
 $ Pond       : chr  "MP1" "UBP3" "UBP4" "MP3" ...
 $ AvgMed_2020: num  7.45 7.13 7.87 5.47 6.77 ...
 $ 2030       : num  9.42 9.09 9.85 7.41 8.74 ...
 $ 2031       : num  6.82 6.5 7.27 4.82 6.14 ...
 $ 2032       : num  8.46 8.13 8.88 6.44 7.78 ...
 $ 2033       : num  9.43 9.1 9.85 7.42 8.72 ...
 $ 2034       : num  7.97 7.63 8.38 5.95 7.26 ...
 $ 2035       : num  8.89 8.55 9.3 6.87 8.19 ...
 $ 2036       : num  8.66 8.33 9.09 6.65 7.96 ...
 $ 2037       : num  10.12 9.8 10.54 8.11 9.43 ...
 $ 2038       : num  9.55 9.24 9.98 7.54 8.87 ...
 $ 2039       : num  8.12 7.81 8.55 6.11 7.44 ...
 $ 2060       : num  10.86 10.53 11.28 8.84 10.17 ...
 $ 2061       : num  11.09 10.78 11.53 9.09 10.4 ...
 $ 2062       : num  12.5 12.2 13 10.6 11.9 ...
 $ 2063       : num  14.2 13.9 14.7 12.2 13.5 ...
 $ 2064       : num  11.6 11.28 12.04 9.59 10.92 ...
 $ 2065       : num  10.98 10.66 11.41 8.97 10.29 ...
 $ 2066       : num  12.3 11.9 12.7 10.2 11.6 ...
 $ 2067       : num  11.16 10.82 11.58 9.15 10.47 ...
 $ 2068       : num  11.29 10.98 11.74 9.29 10.6 ...
 $ 2069       : num  12.3 12 12.7 10.3 11.6 ...
 $ 2090       : num  14.2 13.9 14.6 12.2 13.5 ...
 $ 2091       : num  14.8 14.5 15.2 12.8 14.1 ...
 $ 2092       : num  14.3 13.9 14.7 12.3 13.6 ...
 $ 2093       : num  14.5 14.2 14.9 12.5 13.8 ...
 $ 2094       : num  13.9 13.6 14.4 11.9 13.2 ...
 $ 2095       : num  14.4 14.1 14.8 12.3 13.7 ...
 $ 2096       : num  15.2 14.9 15.6 13.2 14.5 ...
 $ 2097       : num  14.7 14.3 15.1 12.7 14 ...
 $ 2098       : num  14.9 14.6 15.3 12.9 14.2 ...
 $ 2099       : num  15.3 15 15.7 13.3 14.6 ...
 $ diff_2030  : num  1.97 1.96 1.98 1.95 1.97 ...
 $ diff_2031  : num  -0.625 -0.633 -0.607 -0.647 -0.629 ...
 $ diff_2032  : num  1.01 1.006 1.009 0.972 1.015 ...
 $ diff_2033  : num  1.98 1.98 1.98 1.95 1.96 ...
 $ diff_2034  : num  0.516 0.502 0.509 0.484 0.493 ...
 $ diff_2035  : num  1.44 1.43 1.43 1.4 1.42 ...
 $ diff_2036  : num  1.21 1.2 1.21 1.18 1.2 ...
 $ diff_2037  : num  2.67 2.67 2.67 2.64 2.66 ...
 $ diff_2038  : num  2.1 2.11 2.1 2.07 2.1 ...
 $ diff_2039  : num  0.675 0.679 0.679 0.639 0.671 ...
 $ diff_2060  : num  3.41 3.41 3.41 3.38 3.4 ...
 $ diff_2061  : num  3.64 3.65 3.66 3.62 3.63 ...
 $ diff_2062  : num  5.1 5.09 5.11 5.1 5.1 ...
 $ diff_2063  : num  6.78 6.78 6.78 6.76 6.76 ...
 $ diff_2064  : num  4.15 4.15 4.17 4.12 4.15 ...
 $ diff_2065  : num  3.53 3.54 3.54 3.51 3.52 ...
 $ diff_2066  : num  4.81 4.82 4.82 4.78 4.82 ...
 $ diff_2067  : num  3.71 3.7 3.71 3.68 3.7 ...
 $ diff_2068  : num  3.84 3.85 3.86 3.82 3.83 ...
 $ diff_2069  : num  4.84 4.82 4.84 4.81 4.83 ...
 $ diff_2090  : num  6.75 6.75 6.77 6.71 6.74 ...
 $ diff_2091  : num  7.39 7.38 7.37 7.35 7.35 ...
 $ diff_2092  : num  6.82 6.82 6.82 6.79 6.82 ...
 $ diff_2093  : num  7.04 7.02 7.03 7.01 7.04 ...
 $ diff_2094  : num  6.49 6.49 6.5 6.47 6.48 ...
 $ diff_2095  : num  6.92 6.93 6.91 6.88 6.9 ...
 $ diff_2096  : num  7.75 7.76 7.76 7.72 7.75 ...
 $ diff_2097  : num  7.22 7.22 7.24 7.2 7.22 ...
 $ diff_2098  : num  7.45 7.44 7.46 7.42 7.44 ...
 $ diff_2099  : num  7.85 7.84 7.85 7.83 7.84 ...
library(matrixStats)
# Create a new dataframe with the calculated means and standard deviations
Delta_YF85 <- Delta_combined_avgMed %>%
  mutate(
    Mean_2030_2039 = rowMeans(select(., starts_with("diff_203")), na.rm = TRUE),  # Calculate row-wise mean for columns starting with "diff_203"
    SD_2030_2039 = rowSds(as.matrix(select(., starts_with("diff_203"))), na.rm = TRUE),  # Calculate row-wise SD for columns starting with "diff_203"
    Mean_2060_2069 = rowMeans(select(., starts_with("diff_206")), na.rm = TRUE),  # Calculate row-wise mean for columns starting with "diff_206"
    SD_2060_2069 = rowSds(as.matrix(select(., starts_with("diff_206"))), na.rm = TRUE),  # Calculate row-wise SD for columns starting with "diff_206"
    Mean_2090_2099 = rowMeans(select(., starts_with("diff_209")), na.rm = TRUE),  # Calculate row-wise mean for columns starting with "diff_209"
    SD_2090_2099 = rowSds(as.matrix(select(., starts_with("diff_209"))), na.rm = TRUE)  # Calculate row-wise SD for columns starting with "diff_209"
  )

# Print the structure of the new dataframe
str(Delta_YF85)
'data.frame':   11 obs. of  68 variables:
 $ Pond          : chr  "MP1" "UBP3" "UBP4" "MP3" ...
 $ AvgMed_2020   : num  7.45 7.13 7.87 5.47 6.77 ...
 $ 2030          : num  9.42 9.09 9.85 7.41 8.74 ...
 $ 2031          : num  6.82 6.5 7.27 4.82 6.14 ...
 $ 2032          : num  8.46 8.13 8.88 6.44 7.78 ...
 $ 2033          : num  9.43 9.1 9.85 7.42 8.72 ...
 $ 2034          : num  7.97 7.63 8.38 5.95 7.26 ...
 $ 2035          : num  8.89 8.55 9.3 6.87 8.19 ...
 $ 2036          : num  8.66 8.33 9.09 6.65 7.96 ...
 $ 2037          : num  10.12 9.8 10.54 8.11 9.43 ...
 $ 2038          : num  9.55 9.24 9.98 7.54 8.87 ...
 $ 2039          : num  8.12 7.81 8.55 6.11 7.44 ...
 $ 2060          : num  10.86 10.53 11.28 8.84 10.17 ...
 $ 2061          : num  11.09 10.78 11.53 9.09 10.4 ...
 $ 2062          : num  12.5 12.2 13 10.6 11.9 ...
 $ 2063          : num  14.2 13.9 14.7 12.2 13.5 ...
 $ 2064          : num  11.6 11.28 12.04 9.59 10.92 ...
 $ 2065          : num  10.98 10.66 11.41 8.97 10.29 ...
 $ 2066          : num  12.3 11.9 12.7 10.2 11.6 ...
 $ 2067          : num  11.16 10.82 11.58 9.15 10.47 ...
 $ 2068          : num  11.29 10.98 11.74 9.29 10.6 ...
 $ 2069          : num  12.3 12 12.7 10.3 11.6 ...
 $ 2090          : num  14.2 13.9 14.6 12.2 13.5 ...
 $ 2091          : num  14.8 14.5 15.2 12.8 14.1 ...
 $ 2092          : num  14.3 13.9 14.7 12.3 13.6 ...
 $ 2093          : num  14.5 14.2 14.9 12.5 13.8 ...
 $ 2094          : num  13.9 13.6 14.4 11.9 13.2 ...
 $ 2095          : num  14.4 14.1 14.8 12.3 13.7 ...
 $ 2096          : num  15.2 14.9 15.6 13.2 14.5 ...
 $ 2097          : num  14.7 14.3 15.1 12.7 14 ...
 $ 2098          : num  14.9 14.6 15.3 12.9 14.2 ...
 $ 2099          : num  15.3 15 15.7 13.3 14.6 ...
 $ diff_2030     : num  1.97 1.96 1.98 1.95 1.97 ...
 $ diff_2031     : num  -0.625 -0.633 -0.607 -0.647 -0.629 ...
 $ diff_2032     : num  1.01 1.006 1.009 0.972 1.015 ...
 $ diff_2033     : num  1.98 1.98 1.98 1.95 1.96 ...
 $ diff_2034     : num  0.516 0.502 0.509 0.484 0.493 ...
 $ diff_2035     : num  1.44 1.43 1.43 1.4 1.42 ...
 $ diff_2036     : num  1.21 1.2 1.21 1.18 1.2 ...
 $ diff_2037     : num  2.67 2.67 2.67 2.64 2.66 ...
 $ diff_2038     : num  2.1 2.11 2.1 2.07 2.1 ...
 $ diff_2039     : num  0.675 0.679 0.679 0.639 0.671 ...
 $ diff_2060     : num  3.41 3.41 3.41 3.38 3.4 ...
 $ diff_2061     : num  3.64 3.65 3.66 3.62 3.63 ...
 $ diff_2062     : num  5.1 5.09 5.11 5.1 5.1 ...
 $ diff_2063     : num  6.78 6.78 6.78 6.76 6.76 ...
 $ diff_2064     : num  4.15 4.15 4.17 4.12 4.15 ...
 $ diff_2065     : num  3.53 3.54 3.54 3.51 3.52 ...
 $ diff_2066     : num  4.81 4.82 4.82 4.78 4.82 ...
 $ diff_2067     : num  3.71 3.7 3.71 3.68 3.7 ...
 $ diff_2068     : num  3.84 3.85 3.86 3.82 3.83 ...
 $ diff_2069     : num  4.84 4.82 4.84 4.81 4.83 ...
 $ diff_2090     : num  6.75 6.75 6.77 6.71 6.74 ...
 $ diff_2091     : num  7.39 7.38 7.37 7.35 7.35 ...
 $ diff_2092     : num  6.82 6.82 6.82 6.79 6.82 ...
 $ diff_2093     : num  7.04 7.02 7.03 7.01 7.04 ...
 $ diff_2094     : num  6.49 6.49 6.5 6.47 6.48 ...
 $ diff_2095     : num  6.92 6.93 6.91 6.88 6.9 ...
 $ diff_2096     : num  7.75 7.76 7.76 7.72 7.75 ...
 $ diff_2097     : num  7.22 7.22 7.24 7.2 7.22 ...
 $ diff_2098     : num  7.45 7.44 7.46 7.42 7.44 ...
 $ diff_2099     : num  7.85 7.84 7.85 7.83 7.84 ...
 $ Mean_2030_2039: num  1.29 1.29 1.3 1.26 1.29 ...
 $ SD_2030_2039  : num  0.957 0.96 0.955 0.957 0.958 ...
 $ Mean_2060_2069: num  4.38 4.38 4.39 4.36 4.38 ...
 $ SD_2060_2069  : num  1.04 1.03 1.03 1.04 1.03 ...
 $ Mean_2090_2099: num  7.17 7.17 7.17 7.14 7.16 ...
 $ SD_2090_2099  : num  0.443 0.44 0.441 0.443 0.444 ...
# Optionally, view the first few rows to check the new columns
head(Delta_YF85)

Put these into total mean/standard deviations

# Load necessary libraries
library(dplyr)

# Select and rename columns from Delta_YF85
YF85_decadal <- Delta_YF85 %>%
  select(Pond, starts_with("Mean_"), starts_with("SD_"))

# Rename columns without the 'Y' prefix for means
names(YF85_decadal) <- sub("^Mean_", "Mean_", names(YF85_decadal))

# Rename columns without the 'Y' prefix for standard deviations
names(YF85_decadal) <- sub("^SD_", "SD_", names(YF85_decadal))

# Print the structure of the updated dataframe
str(YF85_decadal)
'data.frame':   11 obs. of  7 variables:
 $ Pond          : chr  "MP1" "UBP3" "UBP4" "MP3" ...
 $ Mean_2030_2039: num  1.29 1.29 1.3 1.26 1.29 ...
 $ Mean_2060_2069: num  4.38 4.38 4.39 4.36 4.38 ...
 $ Mean_2090_2099: num  7.17 7.17 7.17 7.14 7.16 ...
 $ SD_2030_2039  : num  0.957 0.96 0.955 0.957 0.958 ...
 $ SD_2060_2069  : num  1.04 1.03 1.03 1.04 1.03 ...
 $ SD_2090_2099  : num  0.443 0.44 0.441 0.443 0.444 ...
# Optionally, view the first few rows to check the new columns
head(YF85_decadal)

Making the plots of these deltas

# Load required packages
library(ggplot2)
library(gridExtra)
library(ggpubr)

# Create a grouped bar plot with error bars for Mean 2030
plot_2030 <- ggplot(YF85_decadal, aes(x = Pond, y = Mean_2030_2039)) +
  geom_bar(stat = "identity", fill = "#FFD92F", color = "black") +
  geom_errorbar(aes(ymin = Mean_2030_2039 - SD_2030_2039, ymax = Mean_2030_2039 + SD_2030_2039),
                width = 0.4,  # Adjust the width of error bars as needed
                position = position_dodge(width = 0.9)) +
  labs(x = "", y = "Delta Temp (C)") +
  ylim(-1, 5) +
  theme_classic() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  theme(plot.title = element_text(hjust = 0.5))  # Centered title
plot_2030


# Create a grouped bar plot with error bars for Mean 2060
plot_2060 <- ggplot(YF85_decadal, aes(x = Pond, y = Mean_2060_2069)) +
  geom_bar(stat = "identity", fill = "#F46D43", color = "black") +
  geom_errorbar(aes(ymin = Mean_2060_2069 - SD_2060_2069, ymax = Mean_2060_2069 + SD_2060_2069),
                width = 0.4,  # Adjust the width of error bars as needed
                position = position_dodge(width = 0.9)) +
  labs(x = "", y = "") +  # No y-axis label
  ylim(-1, 5) +
  theme_classic() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  theme(plot.title = element_text(hjust = 0.5)) +  # Centered title 
  theme(axis.text.y = element_blank(),  # Remove Y-axis tick mark labels
        axis.ticks.y = element_blank())   # Remove Y-axis ticks
plot_2060


# Create a grouped bar plot with error bars for Mean 2090
plot_2090 <- ggplot(YF85_decadal, aes(x = Pond, y = Mean_2090_2099)) +
  geom_bar(stat = "identity", fill = "#D73027", color = "black") +
  geom_errorbar(aes(ymin = Mean_2090_2099 - SD_2090_2099, ymax = Mean_2090_2099 + SD_2090_2099),
                width = 0.4,  # Adjust the width of error bars as needed
                position = position_dodge(width = 0.9)) +
  labs(x = "", y = "") +  # No y-axis label
  ylim(-1, 5) +
  theme_classic() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  theme(plot.title = element_text(hjust = 0.5)) +  # Centered title 
  theme(axis.text.y = element_blank(),  # Remove Y-axis tick mark labels
        axis.ticks.y = element_blank())   # Remove Y-axis ticks
plot_2090
Warning: Removed 11 rows containing missing values or values outside the scale range (`geom_bar()`).
# Combine plots into a panel plot
Delta_YF85_plot <- ggarrange(plot_2030, plot_2060, plot_2090, ncol = 3)
Warning: Removed 11 rows containing missing values or values outside the scale range (`geom_bar()`).
# Save the combined plot
ggsave("Corr_DeltaYF85.png", plot = Delta_YF85_plot, width = 8, height = 3)

Statistical tests for each of these ponds for 2030s, 2060s, and 2090s

2030s

Delta_YF85

# Load required libraries
library(dplyr)
library(broom)
library(tidyr)

# Step 1: Prepare the data
data_long <- Delta_YF85 %>%
  select(Pond, matches("^diff_203[0-9]$")) %>%
  pivot_longer(cols = -Pond, names_to = "Year", values_to = "Difference")

boxplot(data_long$Difference ~ data_long$Pond)


# Step 2: Conduct ANOVA by grouping by Pond
res_YF85 <- aov(Difference ~ Pond, data = data_long)
summary(res_YF85)
            Df Sum Sq Mean Sq F value Pr(>F)
Pond        10   0.01  0.0007   0.001      1
Residuals   99  90.74  0.9165               
# Step 3: Tukey HSD
post_test_YF85 <- TukeyHSD(res_YF85)
post_test_YF85
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = Difference ~ Pond, data = data_long)

$Pond
                   diff       lwr      upr p adj
MP3-MP1   -0.0309536340 -1.441778 1.379871     1
MP5-MP1   -0.0084655775 -1.419290 1.402359     1
MP8-MP1   -0.0070506871 -1.417875 1.403774     1
PL1-MP1   -0.0053581246 -1.416183 1.405467     1
PL2-MP1   -0.0077879959 -1.418613 1.403037     1
PL3-MP1   -0.0104036062 -1.421228 1.400421     1
UBP1-MP1  -0.0069344459 -1.417759 1.403890     1
UBP2-MP1  -0.0086695815 -1.419494 1.402155     1
UBP3-MP1  -0.0046855885 -1.415510 1.406139     1
UBP4-MP1   0.0018912822 -1.408933 1.412716     1
MP5-MP3    0.0224880565 -1.388337 1.433313     1
MP8-MP3    0.0239029468 -1.386922 1.434728     1
PL1-MP3    0.0255955093 -1.385229 1.436420     1
PL2-MP3    0.0231656381 -1.387659 1.433990     1
PL3-MP3    0.0205500278 -1.390275 1.431375     1
UBP1-MP3   0.0240191880 -1.386805 1.434844     1
UBP2-MP3   0.0222840525 -1.388541 1.433109     1
UBP3-MP3   0.0262680454 -1.384557 1.437093     1
UBP4-MP3   0.0328449161 -1.377980 1.443670     1
MP8-MP5    0.0014148904 -1.409410 1.412240     1
PL1-MP5    0.0031074529 -1.407717 1.413932     1
PL2-MP5    0.0006775816 -1.410147 1.411502     1
PL3-MP5   -0.0019380287 -1.412763 1.408887     1
UBP1-MP5   0.0015311316 -1.409294 1.412356     1
UBP2-MP5  -0.0002040040 -1.411029 1.410621     1
UBP3-MP5   0.0037799890 -1.407045 1.414605     1
UBP4-MP5   0.0103568597 -1.400468 1.421181     1
PL1-MP8    0.0016925625 -1.409132 1.412517     1
PL2-MP8   -0.0007373087 -1.411562 1.410087     1
PL3-MP8   -0.0033529190 -1.414178 1.407472     1
UBP1-MP8   0.0001162412 -1.410708 1.410941     1
UBP2-MP8  -0.0016188943 -1.412444 1.409206     1
UBP3-MP8   0.0023650986 -1.408460 1.413190     1
UBP4-MP8   0.0089419693 -1.401883 1.419767     1
PL2-PL1   -0.0024298713 -1.413255 1.408395     1
PL3-PL1   -0.0050454816 -1.415870 1.405779     1
UBP1-PL1  -0.0015763213 -1.412401 1.409248     1
UBP2-PL1  -0.0033114569 -1.414136 1.407513     1
UBP3-PL1   0.0006725361 -1.410152 1.411497     1
UBP4-PL1   0.0072494068 -1.403575 1.418074     1
PL3-PL2   -0.0026156103 -1.413440 1.408209     1
UBP1-PL2   0.0008535499 -1.409971 1.411678     1
UBP2-PL2  -0.0008815856 -1.411706 1.409943     1
UBP3-PL2   0.0031024074 -1.407722 1.413927     1
UBP4-PL2   0.0096792781 -1.401145 1.420504     1
UBP1-PL3   0.0034691603 -1.407355 1.414294     1
UBP2-PL3   0.0017340247 -1.409091 1.412559     1
UBP3-PL3   0.0057180177 -1.405107 1.416543     1
UBP4-PL3   0.0122948884 -1.398530 1.423120     1
UBP2-UBP1 -0.0017351355 -1.412560 1.409090     1
UBP3-UBP1  0.0022488574 -1.408576 1.413073     1
UBP4-UBP1  0.0088257281 -1.401999 1.419650     1
UBP3-UBP2  0.0039839930 -1.406841 1.414809     1
UBP4-UBP2  0.0105608637 -1.400264 1.421385     1
UBP4-UBP3  0.0065768707 -1.404248 1.417402     1

2060s

Delta_YF85

# Load required libraries
library(dplyr)
library(broom)

# Step 1: Prepare the data
data_long <- Delta_YF85 %>%
  select(Pond, matches("^diff_206[0-9]$")) %>%
  pivot_longer(cols = -Pond, names_to = "Year", values_to = "Difference")

boxplot(data_long$Difference ~ data_long$Pond)


# Step 2: Conduct ANOVA by grouping by Pond
res_YF85 <- aov(Difference ~ Pond, data = data_long)
summary(res_YF85)
            Df Sum Sq Mean Sq F value Pr(>F)
Pond        10   0.01  0.0006   0.001      1
Residuals   99 106.35  1.0742               
# Step 3: Tukey HSD
post_test_YF85 <- TukeyHSD(res_YF85)
post_test_YF85
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = Difference ~ Pond, data = data_long)

$Pond
                   diff       lwr      upr p adj
MP3-MP1   -0.0239143576 -1.551308 1.503479     1
MP5-MP1   -0.0062309085 -1.533624 1.521162     1
MP8-MP1   -0.0006772301 -1.528070 1.526716     1
PL1-MP1   -0.0037509302 -1.531144 1.523642     1
PL2-MP1   -0.0091502094 -1.536543 1.518243     1
PL3-MP1   -0.0023098736 -1.529703 1.525083     1
UBP1-MP1  -0.0077866481 -1.535180 1.519607     1
UBP2-MP1  -0.0063965106 -1.533790 1.520997     1
UBP3-MP1  -0.0014816268 -1.528875 1.525912     1
UBP4-MP1   0.0080534452 -1.519340 1.535447     1
MP5-MP3    0.0176834491 -1.509710 1.545077     1
MP8-MP3    0.0232371275 -1.504156 1.550630     1
PL1-MP3    0.0201634274 -1.507230 1.547557     1
PL2-MP3    0.0147641481 -1.512629 1.542157     1
PL3-MP3    0.0216044840 -1.505789 1.548998     1
UBP1-MP3   0.0161277094 -1.511266 1.543521     1
UBP2-MP3   0.0175178469 -1.509875 1.544911     1
UBP3-MP3   0.0224327308 -1.504961 1.549826     1
UBP4-MP3   0.0319678027 -1.495425 1.559361     1
MP8-MP5    0.0055536784 -1.521840 1.532947     1
PL1-MP5    0.0024799783 -1.524913 1.529873     1
PL2-MP5   -0.0029193010 -1.530313 1.524474     1
PL3-MP5    0.0039210349 -1.523472 1.531314     1
UBP1-MP5  -0.0015557397 -1.528949 1.525838     1
UBP2-MP5  -0.0001656022 -1.527559 1.527228     1
UBP3-MP5   0.0047492817 -1.522644 1.532143     1
UBP4-MP5   0.0142843536 -1.513109 1.541678     1
PL1-MP8   -0.0030737001 -1.530467 1.524320     1
PL2-MP8   -0.0084729794 -1.535866 1.518920     1
PL3-MP8   -0.0016326435 -1.529026 1.525761     1
UBP1-MP8  -0.0071094181 -1.534503 1.520284     1
UBP2-MP8  -0.0057192806 -1.533113 1.521674     1
UBP3-MP8  -0.0008043967 -1.528198 1.526589     1
UBP4-MP8   0.0087306752 -1.518663 1.536124     1
PL2-PL1   -0.0053992793 -1.532793 1.521994     1
PL3-PL1    0.0014410566 -1.525952 1.528834     1
UBP1-PL1  -0.0040357180 -1.531429 1.523358     1
UBP2-PL1  -0.0026455805 -1.530039 1.524748     1
UBP3-PL1   0.0022693034 -1.525124 1.529663     1
UBP4-PL1   0.0118043753 -1.515589 1.539198     1
PL3-PL2    0.0068403358 -1.520553 1.534234     1
UBP1-PL2   0.0013635613 -1.526030 1.528757     1
UBP2-PL2   0.0027536988 -1.524640 1.530147     1
UBP3-PL2   0.0076685827 -1.519725 1.535062     1
UBP4-PL2   0.0172036546 -1.510190 1.544597     1
UBP1-PL3  -0.0054767745 -1.532870 1.521916     1
UBP2-PL3  -0.0040866370 -1.531480 1.523307     1
UBP3-PL3   0.0008282468 -1.526565 1.528221     1
UBP4-PL3   0.0103633187 -1.517030 1.537757     1
UBP2-UBP1  0.0013901375 -1.526003 1.528783     1
UBP3-UBP1  0.0063050214 -1.521088 1.533698     1
UBP4-UBP1  0.0158400933 -1.511553 1.543233     1
UBP3-UBP2  0.0049148839 -1.522478 1.532308     1
UBP4-UBP2  0.0144499558 -1.512943 1.541843     1
UBP4-UBP3  0.0095350719 -1.517858 1.536928     1

2090s

Delta_YF85

# Load required libraries
library(dplyr)
library(broom)

# Step 1: Prepare the data
data_long <- Delta_YF85 %>%
  select(Pond, matches("^diff_209[0-9]$")) %>%
  pivot_longer(cols = -Pond, names_to = "Year", values_to = "Difference")

boxplot(data_long$Difference ~ data_long$Pond)


# Step 2: Conduct ANOVA by grouping by Pond
res_YF85 <- aov(Difference ~ Pond, data = data_long)
summary(res_YF85)
            Df Sum Sq Mean Sq F value Pr(>F)
Pond        10  0.008 0.00081   0.004      1
Residuals   99 19.461 0.19657               
# Step 3: Tukey HSD
post_test_YF85 <- TukeyHSD(res_YF85)
post_test_YF85
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = Difference ~ Pond, data = data_long)

$Pond
                   diff        lwr       upr p adj
MP3-MP1   -3.113857e-02 -0.6845202 0.6222431     1
MP5-MP1   -9.882966e-03 -0.6632646 0.6434987     1
MP8-MP1   -1.672228e-03 -0.6550539 0.6517094     1
PL1-MP1   -4.243460e-03 -0.6576251 0.6491382     1
PL2-MP1   -6.484398e-03 -0.6598660 0.6468972     1
PL3-MP1   -9.998092e-03 -0.6633797 0.6433835     1
UBP1-MP1  -1.006286e-02 -0.6634445 0.6433188     1
UBP2-MP1  -6.892669e-03 -0.6602743 0.6464890     1
UBP3-MP1  -2.228373e-03 -0.6556100 0.6511533     1
UBP4-MP1   2.448355e-03 -0.6509333 0.6558300     1
MP5-MP3    2.125560e-02 -0.6321260 0.6746372     1
MP8-MP3    2.946634e-02 -0.6239153 0.6828480     1
PL1-MP3    2.689511e-02 -0.6264865 0.6802767     1
PL2-MP3    2.465417e-02 -0.6287275 0.6780358     1
PL3-MP3    2.114047e-02 -0.6322412 0.6745221     1
UBP1-MP3   2.107571e-02 -0.6323059 0.6744573     1
UBP2-MP3   2.424590e-02 -0.6291357 0.6776275     1
UBP3-MP3   2.891019e-02 -0.6244714 0.6822918     1
UBP4-MP3   3.358692e-02 -0.6197947 0.6869686     1
MP8-MP5    8.210738e-03 -0.6451709 0.6615924     1
PL1-MP5    5.639506e-03 -0.6477421 0.6590211     1
PL2-MP5    3.398567e-03 -0.6499831 0.6567802     1
PL3-MP5   -1.151261e-04 -0.6534968 0.6532665     1
UBP1-MP5  -1.798952e-04 -0.6535615 0.6532017     1
UBP2-MP5   2.990296e-03 -0.6503913 0.6563719     1
UBP3-MP5   7.654593e-03 -0.6457270 0.6610362     1
UBP4-MP5   1.233132e-02 -0.6410503 0.6657130     1
PL1-MP8   -2.571232e-03 -0.6559529 0.6508104     1
PL2-MP8   -4.812171e-03 -0.6581938 0.6485695     1
PL3-MP8   -8.325864e-03 -0.6617075 0.6450558     1
UBP1-MP8  -8.390633e-03 -0.6617723 0.6449910     1
UBP2-MP8  -5.220442e-03 -0.6586021 0.6481612     1
UBP3-MP8  -5.561452e-04 -0.6539378 0.6528255     1
UBP4-MP8   4.120582e-03 -0.6492610 0.6575022     1
PL2-PL1   -2.240938e-03 -0.6556226 0.6511407     1
PL3-PL1   -5.754632e-03 -0.6591363 0.6476270     1
UBP1-PL1  -5.819401e-03 -0.6592010 0.6475622     1
UBP2-PL1  -2.649209e-03 -0.6560308 0.6507324     1
UBP3-PL1   2.015087e-03 -0.6513665 0.6553967     1
UBP4-PL1   6.691815e-03 -0.6466898 0.6600734     1
PL3-PL2   -3.513693e-03 -0.6568953 0.6498679     1
UBP1-PL2  -3.578463e-03 -0.6569601 0.6498032     1
UBP2-PL2  -4.082710e-04 -0.6537899 0.6529734     1
UBP3-PL2   4.256025e-03 -0.6491256 0.6576377     1
UBP4-PL2   8.932753e-03 -0.6444489 0.6623144     1
UBP1-PL3  -6.476905e-05 -0.6534464 0.6533169     1
UBP2-PL3   3.105422e-03 -0.6502762 0.6564871     1
UBP3-PL3   7.769719e-03 -0.6456119 0.6611514     1
UBP4-PL3   1.244645e-02 -0.6409352 0.6658281     1
UBP2-UBP1  3.170192e-03 -0.6502114 0.6565518     1
UBP3-UBP1  7.834488e-03 -0.6455471 0.6612161     1
UBP4-UBP1  1.251122e-02 -0.6408704 0.6658928     1
UBP3-UBP2  4.664296e-03 -0.6487173 0.6580459     1
UBP4-UBP2  9.341024e-03 -0.6440406 0.6627227     1
UBP4-UBP3  4.676728e-03 -0.6487049 0.6580584     1

Making plots of error by season

2012-2020

# Extract unique pond names from the dataframe
short_names <- unique(Mod_YF85$pond_name)

# Initialize an empty dataframe to store monthly mean results
monthly_means <- data.frame(Pond = character(), Month = character(), AvgTemp = numeric(), Year = numeric(), stringsAsFactors = FALSE)

# Convert 'time' column to Date class
Mod_YF85$time <- as.Date(Mod_YF85$time, format="%Y-%m-%d")

# Extract year and month from 'time' column
Mod_YF85$Year <- format(Mod_YF85$time, "%Y")
Mod_YF85$Month <- format(Mod_YF85$time, "%B")

# Loop through each unique pond name
for (short_name in short_names) {
  # Filter data for the current pond
  pond_data <- subset(Mod_YF85, pond_name == short_name)
  
  # Loop through each month
  for (month in month.name) {
    # Filter data for the current month
    filtered_data <- subset(pond_data, Month == month)
    
    # Calculate the mean of 'med' for the current month
    avg_med <- mean(filtered_data$med, na.rm = TRUE)
    
    # Append results to monthly_means dataframe
    monthly_means <- rbind(monthly_means, data.frame(Pond = short_name, Month = month, AvgTemp = avg_med, Year = 2020))
  }
}

# Print the monthly means dataframe
print(monthly_means)

# Plotting the data
ggplot(monthly_means, aes(x = Month, y = AvgTemp, color = Pond, group = Pond)) +
  geom_line() +
  geom_point() +
  scale_x_discrete(limits = month.name) +
  labs(title = "Monthly Average Temperatures for Each Pond",
       x = "Month",
       y = "Average Temperature",
       color = "Pond") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

2030, 2060, and 2090

# Define the correct order for months
month_order <- c("January", "February", "March", "April", "May", "June", 
                  "July", "August", "September", "October", "November", "December")

# Recalculate monthly averages with correct month ordering
calculate_monthly_averages <- function(data, decade_start, decade_end) {
  # Initialize empty dataframe to store monthly averages
  monthly_avg_table <- data.frame(Pond = character(), Month = factor(), AvgTemp = numeric(), Year = integer(), stringsAsFactors = FALSE)
  
  # Loop through each year in the decade
  for (yr in decade_start:decade_end) {
    # Filter data for the current year
    yearly_data <- data %>%
      filter(year(time) == yr)
    
    # Loop through each pond
    for (pond_name in unique(data$pond_name)) {
      pond_data <- yearly_data %>%
        filter(pond_name == pond_name)
      
      # Loop through each month
      for (month in month_order) {
        # Filter data for the current month
        monthly_data <- pond_data %>%
          filter(format(time, "%B") == month)
        
        # Calculate the mean of 'med' for the current month
        avg_temp <- mean(monthly_data$med, na.rm = TRUE)
        
        # Append results to monthly_avg_table dataframe
        monthly_avg_table <- rbind(monthly_avg_table, data.frame(Pond = pond_name, Month = factor(month, levels = month_order), AvgTemp = avg_temp, Year = yr))
      }
    }
  }
  
  return(monthly_avg_table)
}

# Calculate monthly averages for each decade
monthly_avgX50_table_2030s <- calculate_monthly_averages(Mod_YF85, 2030, 2039)
monthly_avgX50_table_2060s <- calculate_monthly_averages(Mod_YF85, 2060, 2069)
monthly_avgX50_table_2090s <- calculate_monthly_averages(Mod_YF85, 2090, 2099)

Combine all the monthly average tables into one dataframe

# Add a Decade column to each dataframe
monthly_means <- monthly_means %>%
  mutate(Decade = "2020s")

monthly_avgX50_table_2030s <- monthly_avgX50_table_2030s %>%
  mutate(Decade = "2030s")

monthly_avgX50_table_2060s <- monthly_avgX50_table_2060s %>%
  mutate(Decade = "2060s")

monthly_avgX50_table_2090s <- monthly_avgX50_table_2090s %>%
  mutate(Decade = "2090s")

# Combine all monthly average tables into one dataframe
combined_monthly_avg <- bind_rows(
  monthly_means,
  monthly_avgX50_table_2030s,
  monthly_avgX50_table_2060s,
  monthly_avgX50_table_2090s
)

# Print the combined dataframe
print(combined_monthly_avg)

Calculate the differences here as compared to 2020

# Define the reference year
reference_year <- 2020

# Check if the column exists and is correctly populated
summary(combined_monthly_avg)
     Pond              Month              AvgTemp           Year         Decade         
 Length:4092        Length:4092        Min.   :-0.23   Min.   :2020   Length:4092       
 Class :character   Class :character   1st Qu.: 7.42   1st Qu.:2036   Class :character  
 Mode  :character   Mode  :character   Median :11.18   Median :2064   Mode  :character  
                                       Mean   :11.18   Mean   :2063                     
                                       3rd Qu.:14.94   3rd Qu.:2092                     
                                       Max.   :21.28   Max.   :2099                     
# Calculate average temperature for each month in the reference year
ref_year_avg <- combined_monthly_avg %>%
  filter(Year == reference_year) %>%
  group_by(Month) %>%
  summarise(avg_temp_ref_year = mean(AvgTemp, na.rm = TRUE))

# Join reference year averages with the main dataset
combined_monthly_avg_with_diff <- combined_monthly_avg %>%
  left_join(ref_year_avg, by = "Month") %>%
  mutate(diff_AvgTemp = AvgTemp - avg_temp_ref_year) %>%
  select(-avg_temp_ref_year)  # Remove the reference year average column

# Display the structure to verify
str(combined_monthly_avg_with_diff)
'data.frame':   4092 obs. of  6 variables:
 $ Pond        : chr  "MP1" "MP1" "MP1" "MP1" ...
 $ Month       : chr  "January" "February" "March" "April" ...
 $ AvgTemp     : num  6.53 5.35 5.41 6.97 9.94 ...
 $ Year        : num  2020 2020 2020 2020 2020 2020 2020 2020 2020 2020 ...
 $ Decade      : chr  "2020s" "2020s" "2020s" "2020s" ...
 $ diff_AvgTemp: num  0.487 0.49 0.482 0.487 0.504 ...
# Filter out data for the reference year
DeltaMonthly_YF85 <- combined_monthly_avg_with_diff %>%
  filter(Year != reference_year)

# Display the filtered data
print(DeltaMonthly_YF85)
NA

Calculate mean differences

library(dplyr)

DeltaMonthly_YF85

DiffMonthly_YF85 <- DeltaMonthly_YF85 %>%
  select(Pond, Month, Year, diff_AvgTemp)

# Create a new column based on year ranges
DiffMonthly_YF85$Decade <- ifelse(DiffMonthly_YF85$Year >= 2030 & DiffMonthly_YF85$Year < 2040, "2030s",
                          ifelse(DiffMonthly_YF85$Year >= 2060 & DiffMonthly_YF85$Year < 2070, "2060s",
                          ifelse(DiffMonthly_YF85$Year >= 2090 & DiffMonthly_YF85$Year < 2100, "2090s",
                          "Other")))

# Print the updated data frame
print(DiffMonthly_YF85)
  
# Convert Month to Date type
DiffMonthly_YF85 <- DiffMonthly_YF85 %>%
  mutate(Month = as.Date(paste0(Month, " 1 ", Year), format = "%B %d %Y"))

print(DiffMonthly_YF85)

# Group by Pond and Month, then calculate mean and standard deviation of diff_AvgTemp
summary_stats <- DiffMonthly_YF85 %>%
  dplyr::mutate(Month = format(Month, "%m")) %>%  # Extracts YYYY-MM format
  dplyr::group_by(Pond, Month, Decade) %>%
  dplyr::summarise(
    mean_diff_AvgTemp = mean(diff_AvgTemp, na.rm = TRUE),
    sd_diff_AvgTemp = sd(diff_AvgTemp, na.rm = TRUE)
  )
`summarise()` has grouped output by 'Pond', 'Month'. You can override using the `.groups` argument.
# View the summary statistics
print(summary_stats)

# Group by just Month, then calculate mean and standard deviation of diff_AvgTemp
summary_stats2 <- DiffMonthly_YF85 %>%
  dplyr::mutate(Month = format(Month, "%m")) %>%  # Extracts YYYY-MM format
  dplyr::group_by(Month, Decade) %>%
  dplyr::summarise(
    mean_diff_AvgTemp = mean(diff_AvgTemp, na.rm = TRUE),
    sd_diff_AvgTemp = sd(diff_AvgTemp, na.rm = TRUE)
  )
`summarise()` has grouped output by 'Month'. You can override using the `.groups` argument.
# View the summary statistics
print(summary_stats2)

Plotting the monthly temperature change graphs

2030s

summary_stats # grouped by month and pond
summary_stats2 # grouped by just month

# 2. Monthly averages across ponds
MonthlyStats_2030 <- summary_stats2 %>%
  filter(Decade == "2030s") 

ggplot(data = MonthlyStats_2030, aes(x = Month)) +
  geom_point(aes(y = mean_diff_AvgTemp)) +
  theme_classic()


# Convert Month from character to numeric to ensure proper ordering in ggplot
MonthlyStats_2030$Month <- as.numeric(MonthlyStats_2030$Month)

# Plot using ggplot
MonthlyStats_2030Plot <- ggplot(data = MonthlyStats_2030, aes(x = Month)) +
  geom_line(aes(y = mean_diff_AvgTemp)) +  # Point plot with mean values
  geom_hline(yintercept = 0, linetype = "dashed", color = "black") +  # Horizontal dashed line at y = 0
  geom_ribbon(aes(ymin = mean_diff_AvgTemp - sd_diff_AvgTemp, ymax = mean_diff_AvgTemp + sd_diff_AvgTemp), fill = "blue", alpha = 0.3) +  # Ribbon for positive and negative error based on sd values
  scale_x_continuous(breaks = 1:12, labels = month.abb) +  # Adjust x-axis labels to show month abbreviations
  ylim(-4,6)+
  theme_classic() +
  labs(x = "", y = "Delta Temp (C)") +
  theme(axis.text.x = element_text(angle = 65, hjust = 1)) +
  theme(axis.title = element_text(size = 16),
        axis.text = element_text(size = 14))
MonthlyStats_2030Plot

2060s

# 2. Monthly averages across ponds
MonthlyStats_2060 <- summary_stats2 %>%
  filter(Decade == "2060s") 

ggplot(data = MonthlyStats_2060, aes(x = Month)) +
  geom_point(aes(y = mean_diff_AvgTemp)) +
  theme_classic()


# Convert Month from character to numeric to ensure proper ordering in ggplot
MonthlyStats_2060$Month <- as.numeric(MonthlyStats_2060$Month)

# Plot using ggplot
MonthlyStats_2060Plot <- ggplot(data = MonthlyStats_2060, aes(x = Month)) +
  geom_line(aes(y = mean_diff_AvgTemp)) +  # Point plot with mean values
  geom_hline(yintercept = 0, linetype = "dashed", color = "black") +  # Horizontal dashed line at y = 0
  geom_ribbon(aes(ymin = mean_diff_AvgTemp - sd_diff_AvgTemp, ymax = mean_diff_AvgTemp + sd_diff_AvgTemp), fill = "blue", alpha = 0.3) +  # Ribbon for positive and negative error based on sd values
  scale_x_continuous(breaks = 1:12, labels = month.abb) +  # Adjust x-axis labels to show month abbreviations
  ylim(-4,6)+
  theme_classic() +
  labs(x = "", y = "") +
  theme(axis.text.x = element_text(angle = 65, hjust = 1)) +
  theme(axis.title = element_text(size = 16),
        axis.text = element_text(size = 14))+
  theme(axis.text.y = element_blank(),  # Remove Y-axis tick mark labels
        axis.ticks.y = element_blank())
MonthlyStats_2060Plot

2090s

# 2. Monthly averages across ponds
MonthlyStats_2090 <- summary_stats2 %>%
  filter(Decade == "2090s") 

ggplot(data = MonthlyStats_2090, aes(x = Month)) +
  geom_point(aes(y = mean_diff_AvgTemp)) +
  theme_classic()


# Convert Month from character to numeric to ensure proper ordering in ggplot
MonthlyStats_2090$Month <- as.numeric(MonthlyStats_2090$Month)

# Plot using ggplot
MonthlyStats_2090Plot <- ggplot(data = MonthlyStats_2090, aes(x = Month)) +
  geom_line(aes(y = mean_diff_AvgTemp)) +  # Point plot with mean values
  geom_hline(yintercept = 0, linetype = "dashed", color = "black") +  # Horizontal dashed line at y = 0
  geom_ribbon(aes(ymin = mean_diff_AvgTemp - sd_diff_AvgTemp, ymax = mean_diff_AvgTemp + sd_diff_AvgTemp), fill = "blue", alpha = 0.3) +  # Ribbon for positive and negative error based on sd values
  scale_x_continuous(breaks = 1:12, labels = month.abb) +  # Adjust x-axis labels to show month abbreviations
  ylim(-4,6)+
  theme_classic() +
  theme(axis.text.x = element_text(angle = 65, hjust = 1)) +
  labs(x = "", y = "") +
  theme(axis.title = element_text(size = 16),
        axis.text = element_text(size = 14))+
  theme(axis.text.y = element_blank(),  # Remove Y-axis tick mark labels
        axis.ticks.y = element_blank())
MonthlyStats_2090Plot

Combine the plots together here for now

# Combine plots into a panel plot
DeltaMonth_YF85_plot <- ggarrange(MonthlyStats_2030Plot, MonthlyStats_2060Plot, MonthlyStats_2090Plot, ncol = 3)

# Save the combined plot
ggsave("Corr_DeltaMonthYF85.png", plot = DeltaMonth_YF85_plot, width = 12, height = 3)

Create .csv files of the data for these graphs

write.csv(MonthlyStats_2030, file = "Corr_MonthlyStatsYF85_2030.csv")
write.csv(MonthlyStats_2060, file = "Corr_MonthlyStatsYF85_2060.csv")
write.csv(MonthlyStats_2090, file = "Corr_MonthlyStatsYF85_2090.csv")
LS0tCnRpdGxlOiAiUG9uZCBUZW1wcyAtIERlbHRhIEdyYXBocyBhbmQgU2Vhc29uYWwgVHJlbmRzIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tClRoaXMgaXMgY29kZSB1c2VkIHRvIG1ha2UgcGxvdHMgYmFzZWQgb24gb3V0cHV0IGZyb20gdGhlICJJbmRpdmlkdWFsUG9uZE1vZGVsc19Gb3JlY2FzdHM4NSIgZm9yIGJvdGh0aGUgQ1IgYW5kIFlGClJlYWQgaW4gdGhlIG91dHB1dCBmaWxlcyBmb3IgZWFjaCBwb25kL1JDUCBjb21iaW5hdGlvbiB0aGVuIHdvcmsgb24gZGVsdGEgZmlndXJlcyBhbmQgZmlndXJlcyBsaWtlIEhhbWxldCBldCBhbC4gMjAyMAoKYGBge3J9CnJtKGxpc3QgPSBscygpKQoKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkocmphZ3MpCmxpYnJhcnkoZ2dwbG90MikKCnNldC5zZWVkKDEpCmBgYAoKU3RhcnRpbmcgd2l0aCB0aGUgWWFrdXRhdCBGb3JlbGFuZHMKClJDUCA4NQoKIyBSZWFkaW5nIGluIHRoZSBkYXRhCmBgYHtyfQpNb2RfWUY4NSA8LSByZWFkLmNzdigiQ29ycl9Nb2RfWUY4NS5jc3YiLCBoZWFkZXIgPSBUKQpgYGAKCiAKIyMjIDIwMTItMjAyMApgYGB7cn0KIyBMaXN0IG9mIHVuaXF1ZSBwb25kIG5hbWVzIGZyb20gdGhlIGRhdGFmcmFtZQpwb25kX25hbWVzIDwtIHVuaXF1ZShNb2RfWUY4NSRwb25kX25hbWUpCgojIEluaXRpYWxpemUgYW4gZW1wdHkgZGF0YWZyYW1lIHRvIHN0b3JlIHJlc3VsdHMKYXZnTWVkXzIwMjAgPC0gZGF0YS5mcmFtZShQb25kID0gcG9uZF9uYW1lcywgQXZnTWVkXzIwMjAgPSBudW1lcmljKGxlbmd0aChwb25kX25hbWVzKSkpCgojIExvb3AgdGhyb3VnaCBlYWNoIHBvbmQgbmFtZQpmb3IgKGkgaW4gc2VxX2Fsb25nKHBvbmRfbmFtZXMpKSB7CiAgcG9uZF9uYW1lIDwtIHBvbmRfbmFtZXNbaV0KICAKICAjIEZpbHRlciBkYXRhIGZvciB0aGUgY3VycmVudCBwb25kIGFuZCBmb3IgZGF0ZXMgYmVmb3JlIEphbnVhcnkgMSwgMjAyMQogIGZpbHRlcmVkX2RhdGEgPC0gTW9kX1lGODUgJT4lCiAgICBmaWx0ZXIocG9uZF9uYW1lID09ICEhcG9uZF9uYW1lLCBhcy5EYXRlKHRpbWUpIDwgYXMuRGF0ZSgiMjAyMS0wMS0wMSIpKQogIAogICMgQ2FsY3VsYXRlIHRoZSBtZWFuIG9mICdtZWQnICh3aGljaCBjb3JyZXNwb25kcyB0byBYNTAlKQogIGF2Z19tZWQgPC0gbWVhbihmaWx0ZXJlZF9kYXRhJG1lZCwgbmEucm0gPSBUUlVFKQogIAogICMgU3RvcmUgdGhlIHJlc3VsdCBpbiB0aGUgZGF0YWZyYW1lCiAgYXZnTWVkXzIwMjBbaSwgIkF2Z01lZF8yMDIwIl0gPC0gYXZnX21lZAp9CgojIFByaW50IHRoZSBkYXRhZnJhbWUKcHJpbnQoYXZnTWVkXzIwMjApCmBgYAoKIyMjIDIwMzAtMjAzOQpgYGB7cn0KbGlicmFyeShsdWJyaWRhdGUpCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkodGlkeXIpCmxpYnJhcnkoZ2dwbG90MikKCiMgTGlzdCBvZiB1bmlxdWUgcG9uZCBuYW1lcyBmcm9tIHRoZSBkYXRhZnJhbWUKcG9uZF9uYW1lcyA8LSB1bmlxdWUoTW9kX1lGODUkcG9uZF9uYW1lKQoKIyBJbml0aWFsaXplIGEgZGF0YWZyYW1lIHRvIHN0b3JlIHJlc3VsdHMgd2l0aCB5ZWFycyBhcyBjb2x1bW5zCmF2Z01lZF8yMDMwIDwtIGRhdGEuZnJhbWUoUG9uZCA9IHBvbmRfbmFtZXMpCgojIExvb3AgdGhyb3VnaCBlYWNoIHllYXIgZnJvbSAyMDMwIHRvIDIwMzkKZm9yICh5ciBpbiAyMDMwOjIwMzkpIHsKICAjIENhbGN1bGF0ZSBhdmVyYWdlIG1lZGlhbnMgZm9yIGVhY2ggeWVhciBhbmQgc3RvcmUgYXMgYSBuZXcgY29sdW1uCiAgYXZnTWVkX2NvbCA8LSBzYXBwbHkocG9uZF9uYW1lcywgZnVuY3Rpb24ocG9uZF9uYW1lKSB7CiAgICB5ZWFybHlfZGF0YSA8LSBNb2RfWUY4NSAlPiUKICAgICAgZmlsdGVyKHBvbmRfbmFtZSA9PSAhIXBvbmRfbmFtZSwgeWVhcihhcy5EYXRlKHRpbWUpKSA9PSB5cikKICAgIAogICAgYXZnX21lZCA8LSBtZWFuKHllYXJseV9kYXRhJG1lZCwgbmEucm0gPSBUUlVFKQogICAgcmV0dXJuKGF2Z19tZWQpCiAgfSkKICAKICAjIEFkZCB0aGUgcmVzdWx0cyBhcyBhIG5ldyBjb2x1bW4gdG8gdGhlIGRhdGFmcmFtZQogIGF2Z01lZF8yMDMwW1thcy5jaGFyYWN0ZXIoeXIpXV0gPC0gYXZnTWVkX2NvbAp9CgojIFByaW50IHRoZSBmaW5hbCBkYXRhZnJhbWUKcHJpbnQoYXZnTWVkXzIwMzApCgojIENvbnZlcnQgdG8gbG9uZyBmb3JtYXQgZm9yIGdncGxvdDIKYXZnTWVkXzIwMzBfbG9uZyA8LSBhdmdNZWRfMjAzMCAlPiUKICBwaXZvdF9sb25nZXIoY29scyA9IC1Qb25kLCBuYW1lc190byA9ICJZZWFyIiwgdmFsdWVzX3RvID0gIkF2Z01lZCIpCgojIFBsb3QgdGhlIGRhdGEKZ2dwbG90KGF2Z01lZF8yMDMwX2xvbmcsIGFlcyh4ID0gWWVhciwgeSA9IEF2Z01lZCwgY29sb3IgPSBQb25kLCBncm91cCA9IFBvbmQpKSArCiAgZ2VvbV9saW5lKCkgKwogIGdlb21fcG9pbnQoKSArCiAgbGFicyh0aXRsZSA9ICJBdmVyYWdlIE1lZGlhbiBwZXIgUG9uZCBmcm9tIDIwMzAgdG8gMjAzOSIsCiAgICAgICB4ID0gIlllYXIiLAogICAgICAgeSA9ICJBdmVyYWdlIE1lZGlhbiIpICsKICB0aGVtZV9taW5pbWFsKCkKYGBgCgojIyMgMjA2MC0yMDY5CmBgYHtyfQpsaWJyYXJ5KGx1YnJpZGF0ZSkKbGlicmFyeShkcGx5cikKbGlicmFyeSh0aWR5cikKbGlicmFyeShnZ3Bsb3QyKQoKIyBMaXN0IG9mIHVuaXF1ZSBwb25kIG5hbWVzIGZyb20gdGhlIGRhdGFmcmFtZQpwb25kX25hbWVzIDwtIHVuaXF1ZShNb2RfWUY4NSRwb25kX25hbWUpCgojIEluaXRpYWxpemUgYSBkYXRhZnJhbWUgdG8gc3RvcmUgcmVzdWx0cyB3aXRoIHllYXJzIGFzIGNvbHVtbnMKYXZnTWVkXzIwNjAgPC0gZGF0YS5mcmFtZShQb25kID0gcG9uZF9uYW1lcykKCiMgTG9vcCB0aHJvdWdoIGVhY2ggeWVhciBmcm9tIDIwNjAgdG8gMjA2OQpmb3IgKHlyIGluIDIwNjA6MjA2OSkgewogICMgQ2FsY3VsYXRlIGF2ZXJhZ2UgbWVkaWFucyBmb3IgZWFjaCB5ZWFyIGFuZCBzdG9yZSBhcyBhIG5ldyBjb2x1bW4KICBhdmdNZWRfY29sIDwtIHNhcHBseShwb25kX25hbWVzLCBmdW5jdGlvbihwb25kX25hbWUpIHsKICAgIHllYXJseV9kYXRhIDwtIE1vZF9ZRjg1ICU+JQogICAgICBmaWx0ZXIocG9uZF9uYW1lID09ICEhcG9uZF9uYW1lLCB5ZWFyKGFzLkRhdGUodGltZSkpID09IHlyKQogICAgCiAgICBhdmdfbWVkIDwtIG1lYW4oeWVhcmx5X2RhdGEkbWVkLCBuYS5ybSA9IFRSVUUpCiAgICByZXR1cm4oYXZnX21lZCkKICB9KQogIAogICMgQWRkIHRoZSByZXN1bHRzIGFzIGEgbmV3IGNvbHVtbiB0byB0aGUgZGF0YWZyYW1lCiAgYXZnTWVkXzIwNjBbW2FzLmNoYXJhY3Rlcih5cildXSA8LSBhdmdNZWRfY29sCn0KCiMgUHJpbnQgdGhlIGZpbmFsIGRhdGFmcmFtZQpwcmludChhdmdNZWRfMjA2MCkKCiMgQ29udmVydCB0byBsb25nIGZvcm1hdCBmb3IgZ2dwbG90MgphdmdNZWRfMjA2MF9sb25nIDwtIGF2Z01lZF8yMDYwICU+JQogIHBpdm90X2xvbmdlcihjb2xzID0gLVBvbmQsIG5hbWVzX3RvID0gIlllYXIiLCB2YWx1ZXNfdG8gPSAiQXZnTWVkIikKCiMgUGxvdCB0aGUgZGF0YQpnZ3Bsb3QoYXZnTWVkXzIwNjBfbG9uZywgYWVzKHggPSBZZWFyLCB5ID0gQXZnTWVkLCBjb2xvciA9IFBvbmQsIGdyb3VwID0gUG9uZCkpICsKICBnZW9tX2xpbmUoKSArCiAgZ2VvbV9wb2ludCgpICsKICBsYWJzKHRpdGxlID0gIkF2ZXJhZ2UgTWVkaWFuIHBlciBQb25kIGZyb20gMjA2MCB0byAyMDY5IiwKICAgICAgIHggPSAiWWVhciIsCiAgICAgICB5ID0gIkF2ZXJhZ2UgTWVkaWFuIikgKwogIHRoZW1lX21pbmltYWwoKQpgYGAKCiMjIyAyMDkwLTIwOTkKYGBge3J9CmxpYnJhcnkobHVicmlkYXRlKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KHRpZHlyKQpsaWJyYXJ5KGdncGxvdDIpCgojIExpc3Qgb2YgdW5pcXVlIHBvbmQgbmFtZXMgZnJvbSB0aGUgZGF0YWZyYW1lCnBvbmRfbmFtZXMgPC0gdW5pcXVlKE1vZF9ZRjg1JHBvbmRfbmFtZSkKCiMgSW5pdGlhbGl6ZSBhIGRhdGFmcmFtZSB0byBzdG9yZSByZXN1bHRzIHdpdGggeWVhcnMgYXMgY29sdW1ucwphdmdNZWRfMjA5MCA8LSBkYXRhLmZyYW1lKFBvbmQgPSBwb25kX25hbWVzKQoKIyBMb29wIHRocm91Z2ggZWFjaCB5ZWFyIGZyb20gMjA5MCB0byAyMDk5CmZvciAoeXIgaW4gMjA5MDoyMDk5KSB7CiAgIyBDYWxjdWxhdGUgYXZlcmFnZSBtZWRpYW5zIGZvciBlYWNoIHllYXIgYW5kIHN0b3JlIGFzIGEgbmV3IGNvbHVtbgogIGF2Z01lZF9jb2wgPC0gc2FwcGx5KHBvbmRfbmFtZXMsIGZ1bmN0aW9uKHBvbmRfbmFtZSkgewogICAgeWVhcmx5X2RhdGEgPC0gTW9kX1lGODUgJT4lCiAgICAgIGZpbHRlcihwb25kX25hbWUgPT0gISFwb25kX25hbWUsIHllYXIoYXMuRGF0ZSh0aW1lKSkgPT0geXIpCiAgICAKICAgIGF2Z19tZWQgPC0gbWVhbih5ZWFybHlfZGF0YSRtZWQsIG5hLnJtID0gVFJVRSkKICAgIHJldHVybihhdmdfbWVkKQogIH0pCiAgCiAgIyBBZGQgdGhlIHJlc3VsdHMgYXMgYSBuZXcgY29sdW1uIHRvIHRoZSBkYXRhZnJhbWUKICBhdmdNZWRfMjA5MFtbYXMuY2hhcmFjdGVyKHlyKV1dIDwtIGF2Z01lZF9jb2wKfQoKIyBQcmludCB0aGUgZmluYWwgZGF0YWZyYW1lCnByaW50KGF2Z01lZF8yMDkwKQoKIyBDb252ZXJ0IHRvIGxvbmcgZm9ybWF0IGZvciBnZ3Bsb3QyCmF2Z01lZF8yMDkwX2xvbmcgPC0gYXZnTWVkXzIwOTAgJT4lCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSAtUG9uZCwgbmFtZXNfdG8gPSAiWWVhciIsIHZhbHVlc190byA9ICJBdmdNZWQiKQoKIyBQbG90IHRoZSBkYXRhCmdncGxvdChhdmdNZWRfMjA5MF9sb25nLCBhZXMoeCA9IFllYXIsIHkgPSBBdmdNZWQsIGNvbG9yID0gUG9uZCwgZ3JvdXAgPSBQb25kKSkgKwogIGdlb21fbGluZSgpICsKICBnZW9tX3BvaW50KCkgKwogIGxhYnModGl0bGUgPSAiQXZlcmFnZSBNZWRpYW4gcGVyIFBvbmQgZnJvbSAyMDkwIHRvIDIwOTkiLAogICAgICAgeCA9ICJZZWFyIiwKICAgICAgIHkgPSAiQXZlcmFnZSBNZWRpYW4iKSArCiAgdGhlbWVfbWluaW1hbCgpCmBgYApgYGB7cn0KIyBSZW5hbWUgY29sdW1ucyB0byByZWZsZWN0IG9ubHkgdGhlIHllYXJzCmF2Z01lZF8yMDIwIDwtIGF2Z01lZF8yMDIwICU+JQogIHJlbmFtZShBdmdNZWRfMjAyMCA9IEF2Z01lZF8yMDIwKQoKYXZnTWVkXzIwMzAgPC0gYXZnTWVkXzIwMzAgJT4lCiAgcmVuYW1lKGAyMDMwYCA9IGAyMDMwYCkKCmF2Z01lZF8yMDYwIDwtIGF2Z01lZF8yMDYwICU+JQogIHJlbmFtZShgMjA2MGAgPSBgMjA2MGApCgphdmdNZWRfMjA5MCA8LSBhdmdNZWRfMjA5MCAlPiUKICByZW5hbWUoYDIwOTBgID0gYDIwOTBgKQoKIyBDb21iaW5lIHRoZSBkYXRhIGZyYW1lcwpjb21iaW5lZF9hdmdNZWQgPC0gYXZnTWVkXzIwMjAgJT4lCiAgbGVmdF9qb2luKGF2Z01lZF8yMDMwLCBieSA9ICJQb25kIikgJT4lCiAgbGVmdF9qb2luKGF2Z01lZF8yMDYwLCBieSA9ICJQb25kIikgJT4lCiAgbGVmdF9qb2luKGF2Z01lZF8yMDkwLCBieSA9ICJQb25kIikKCiMgUHJpbnQgdGhlIGZpbmFsIGRhdGFmcmFtZQpwcmludChjb21iaW5lZF9hdmdNZWQpCgojIENvbnZlcnQgdG8gbG9uZyBmb3JtYXQgZm9yIGdncGxvdDIsIGV4Y2x1ZGluZyBBdmdNZWRfMjAyMAphdmdNZWRfbG9uZyA8LSBjb21iaW5lZF9hdmdNZWQgJT4lCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSAtUG9uZCwgbmFtZXNfdG8gPSAiWWVhciIsIHZhbHVlc190byA9ICJBdmdNZWQiKSAlPiUKICBmaWx0ZXIoWWVhciAlaW4lIGFzLmNoYXJhY3RlcigyMDIxOjIxOTkpKQoKIyBQbG90IHRoZSBkYXRhCmdncGxvdChhdmdNZWRfbG9uZywgYWVzKHggPSBZZWFyLCB5ID0gQXZnTWVkLCBjb2xvciA9IFBvbmQsIGdyb3VwID0gUG9uZCkpICsKICBnZW9tX2xpbmUoKSArCiAgZ2VvbV9wb2ludCgpICsKICBsYWJzKHRpdGxlID0gIkF2ZXJhZ2UgTWVkaWFuIHBlciBQb25kIGluIHRoZSBZRiAtIFJDUCA4LjUiLAogICAgICAgeCA9ICJZZWFyIiwKICAgICAgIHkgPSAiQXZlcmFnZSBNZWRpYW4iKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpLCMgUm90YXRlIHgtYXhpcyBsYWJlbHMgYnkgNDUgZGVncmVlcwogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKSAgCmBgYAoKCiMgQ2FsY3VhdGUgdGhlIGRpZmZlcmVuY2VzIGhlcmUgYXMgbmV3IGNvbHVtbnMgaW4gdGhlIGRhdGFmcmFtZQoKYGBge3J9CmxpYnJhcnkoZHBseXIpCgojIEFzc3VtaW5nIGNvbWJpbmVkX2F2Z01lZCBpcyBsb2FkZWQgYW5kIHN0cnVjdHVyZSB2ZXJpZmllZApEZWx0YV9jb21iaW5lZF9hdmdNZWQgPC0gY29tYmluZWRfYXZnTWVkICAjIFVzZSB5b3VyIGFjdHVhbCBkYXRhZnJhbWUKCiMgQ29sdW1ucyB0byBjYWxjdWxhdGUgZGlmZmVyZW5jZXMgZm9yCnllYXJzIDwtIGMoIjIwMzAiLCAiMjAzMSIsICIyMDMyIiwgIjIwMzMiLCAiMjAzNCIsIAogICAgICAgICAgICIyMDM1IiwgIjIwMzYiLCAiMjAzNyIsICIyMDM4IiwgIjIwMzkiLCAKICAgICAgICAgICAiMjA2MCIsICIyMDYxIiwgIjIwNjIiLCAiMjA2MyIsICIyMDY0IiwgCiAgICAgICAgICAgIjIwNjUiLCAiMjA2NiIsICIyMDY3IiwgIjIwNjgiLCAiMjA2OSIsIAogICAgICAgICAgICIyMDkwIiwgIjIwOTEiLCAiMjA5MiIsICIyMDkzIiwgIjIwOTQiLCAKICAgICAgICAgICAiMjA5NSIsICIyMDk2IiwgIjIwOTciLCAiMjA5OCIsICIyMDk5IikKCiMgTG9vcCB0aHJvdWdoIGVhY2ggeWVhciBhbmQgY2FsY3VsYXRlIHRoZSBkaWZmZXJlbmNlCmZvciAoeWVhciBpbiB5ZWFycykgewogICMgQ3JlYXRlIGEgbmV3IGNvbHVtbiBmb3IgdGhlIGRpZmZlcmVuY2UKICBkaWZmX2NvbF9uYW1lIDwtIHBhc3RlMCgiZGlmZl8iLCB5ZWFyKQogIERlbHRhX2NvbWJpbmVkX2F2Z01lZFtbZGlmZl9jb2xfbmFtZV1dIDwtIERlbHRhX2NvbWJpbmVkX2F2Z01lZFtbeWVhcl1dIC0gRGVsdGFfY29tYmluZWRfYXZnTWVkJGBBdmdNZWRfMjAyMGAKfQoKIyBEaXNwbGF5IHRoZSBzdHJ1Y3R1cmUgb2YgRGVsdGFfY29tYmluZWRfYXZnTWVkIHRvIHZlcmlmeQpzdHIoRGVsdGFfY29tYmluZWRfYXZnTWVkKQpgYGAKCmBgYHtyfQpsaWJyYXJ5KG1hdHJpeFN0YXRzKQojIENyZWF0ZSBhIG5ldyBkYXRhZnJhbWUgd2l0aCB0aGUgY2FsY3VsYXRlZCBtZWFucyBhbmQgc3RhbmRhcmQgZGV2aWF0aW9ucwpEZWx0YV9ZRjg1IDwtIERlbHRhX2NvbWJpbmVkX2F2Z01lZCAlPiUKICBtdXRhdGUoCiAgICBNZWFuXzIwMzBfMjAzOSA9IHJvd01lYW5zKHNlbGVjdCguLCBzdGFydHNfd2l0aCgiZGlmZl8yMDMiKSksIG5hLnJtID0gVFJVRSksICAjIENhbGN1bGF0ZSByb3ctd2lzZSBtZWFuIGZvciBjb2x1bW5zIHN0YXJ0aW5nIHdpdGggImRpZmZfMjAzIgogICAgU0RfMjAzMF8yMDM5ID0gcm93U2RzKGFzLm1hdHJpeChzZWxlY3QoLiwgc3RhcnRzX3dpdGgoImRpZmZfMjAzIikpKSwgbmEucm0gPSBUUlVFKSwgICMgQ2FsY3VsYXRlIHJvdy13aXNlIFNEIGZvciBjb2x1bW5zIHN0YXJ0aW5nIHdpdGggImRpZmZfMjAzIgogICAgTWVhbl8yMDYwXzIwNjkgPSByb3dNZWFucyhzZWxlY3QoLiwgc3RhcnRzX3dpdGgoImRpZmZfMjA2IikpLCBuYS5ybSA9IFRSVUUpLCAgIyBDYWxjdWxhdGUgcm93LXdpc2UgbWVhbiBmb3IgY29sdW1ucyBzdGFydGluZyB3aXRoICJkaWZmXzIwNiIKICAgIFNEXzIwNjBfMjA2OSA9IHJvd1Nkcyhhcy5tYXRyaXgoc2VsZWN0KC4sIHN0YXJ0c193aXRoKCJkaWZmXzIwNiIpKSksIG5hLnJtID0gVFJVRSksICAjIENhbGN1bGF0ZSByb3ctd2lzZSBTRCBmb3IgY29sdW1ucyBzdGFydGluZyB3aXRoICJkaWZmXzIwNiIKICAgIE1lYW5fMjA5MF8yMDk5ID0gcm93TWVhbnMoc2VsZWN0KC4sIHN0YXJ0c193aXRoKCJkaWZmXzIwOSIpKSwgbmEucm0gPSBUUlVFKSwgICMgQ2FsY3VsYXRlIHJvdy13aXNlIG1lYW4gZm9yIGNvbHVtbnMgc3RhcnRpbmcgd2l0aCAiZGlmZl8yMDkiCiAgICBTRF8yMDkwXzIwOTkgPSByb3dTZHMoYXMubWF0cml4KHNlbGVjdCguLCBzdGFydHNfd2l0aCgiZGlmZl8yMDkiKSkpLCBuYS5ybSA9IFRSVUUpICAjIENhbGN1bGF0ZSByb3ctd2lzZSBTRCBmb3IgY29sdW1ucyBzdGFydGluZyB3aXRoICJkaWZmXzIwOSIKICApCgojIFByaW50IHRoZSBzdHJ1Y3R1cmUgb2YgdGhlIG5ldyBkYXRhZnJhbWUKc3RyKERlbHRhX1lGODUpCgojIE9wdGlvbmFsbHksIHZpZXcgdGhlIGZpcnN0IGZldyByb3dzIHRvIGNoZWNrIHRoZSBuZXcgY29sdW1ucwpoZWFkKERlbHRhX1lGODUpCmBgYAoKIyMgUHV0IHRoZXNlIGludG8gdG90YWwgbWVhbi9zdGFuZGFyZCBkZXZpYXRpb25zCgpgYGB7cn0KIyBMb2FkIG5lY2Vzc2FyeSBsaWJyYXJpZXMKbGlicmFyeShkcGx5cikKCiMgU2VsZWN0IGFuZCByZW5hbWUgY29sdW1ucyBmcm9tIERlbHRhX1lGODUKWUY4NV9kZWNhZGFsIDwtIERlbHRhX1lGODUgJT4lCiAgc2VsZWN0KFBvbmQsIHN0YXJ0c193aXRoKCJNZWFuXyIpLCBzdGFydHNfd2l0aCgiU0RfIikpCgojIFJlbmFtZSBjb2x1bW5zIHdpdGhvdXQgdGhlICdZJyBwcmVmaXggZm9yIG1lYW5zCm5hbWVzKFlGODVfZGVjYWRhbCkgPC0gc3ViKCJeTWVhbl8iLCAiTWVhbl8iLCBuYW1lcyhZRjg1X2RlY2FkYWwpKQoKIyBSZW5hbWUgY29sdW1ucyB3aXRob3V0IHRoZSAnWScgcHJlZml4IGZvciBzdGFuZGFyZCBkZXZpYXRpb25zCm5hbWVzKFlGODVfZGVjYWRhbCkgPC0gc3ViKCJeU0RfIiwgIlNEXyIsIG5hbWVzKFlGODVfZGVjYWRhbCkpCgojIFByaW50IHRoZSBzdHJ1Y3R1cmUgb2YgdGhlIHVwZGF0ZWQgZGF0YWZyYW1lCnN0cihZRjg1X2RlY2FkYWwpCgojIE9wdGlvbmFsbHksIHZpZXcgdGhlIGZpcnN0IGZldyByb3dzIHRvIGNoZWNrIHRoZSBuZXcgY29sdW1ucwpoZWFkKFlGODVfZGVjYWRhbCkKYGBgCgojIE1ha2luZyB0aGUgcGxvdHMgb2YgdGhlc2UgZGVsdGFzCmBgYHtyfQojIExvYWQgcmVxdWlyZWQgcGFja2FnZXMKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGdyaWRFeHRyYSkKbGlicmFyeShnZ3B1YnIpCgojIENyZWF0ZSBhIGdyb3VwZWQgYmFyIHBsb3Qgd2l0aCBlcnJvciBiYXJzIGZvciBNZWFuIDIwMzAKcGxvdF8yMDMwIDwtIGdncGxvdChZRjg1X2RlY2FkYWwsIGFlcyh4ID0gUG9uZCwgeSA9IE1lYW5fMjAzMF8yMDM5KSkgKwogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBmaWxsID0gIiNGRkQ5MkYiLCBjb2xvciA9ICJibGFjayIpICsKICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluID0gTWVhbl8yMDMwXzIwMzkgLSBTRF8yMDMwXzIwMzksIHltYXggPSBNZWFuXzIwMzBfMjAzOSArIFNEXzIwMzBfMjAzOSksCiAgICAgICAgICAgICAgICB3aWR0aCA9IDAuNCwgICMgQWRqdXN0IHRoZSB3aWR0aCBvZiBlcnJvciBiYXJzIGFzIG5lZWRlZAogICAgICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuOSkpICsKICBsYWJzKHggPSAiIiwgeSA9ICJEZWx0YSBUZW1wIChDKSIpICsKICB5bGltKC0xLCA1KSArCiAgdGhlbWVfY2xhc3NpYygpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKSArCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpICAjIENlbnRlcmVkIHRpdGxlCnBsb3RfMjAzMAoKIyBDcmVhdGUgYSBncm91cGVkIGJhciBwbG90IHdpdGggZXJyb3IgYmFycyBmb3IgTWVhbiAyMDYwCnBsb3RfMjA2MCA8LSBnZ3Bsb3QoWUY4NV9kZWNhZGFsLCBhZXMoeCA9IFBvbmQsIHkgPSBNZWFuXzIwNjBfMjA2OSkpICsKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgZmlsbCA9ICIjRjQ2RDQzIiwgY29sb3IgPSAiYmxhY2siKSArCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbiA9IE1lYW5fMjA2MF8yMDY5IC0gU0RfMjA2MF8yMDY5LCB5bWF4ID0gTWVhbl8yMDYwXzIwNjkgKyBTRF8yMDYwXzIwNjkpLAogICAgICAgICAgICAgICAgd2lkdGggPSAwLjQsICAjIEFkanVzdCB0aGUgd2lkdGggb2YgZXJyb3IgYmFycyBhcyBuZWVkZWQKICAgICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjkpKSArCiAgbGFicyh4ID0gIiIsIHkgPSAiIikgKyAgIyBObyB5LWF4aXMgbGFiZWwKICB5bGltKC0xLCA1KSArCiAgdGhlbWVfY2xhc3NpYygpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKSArCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpICsgICMgQ2VudGVyZWQgdGl0bGUgCiAgdGhlbWUoYXhpcy50ZXh0LnkgPSBlbGVtZW50X2JsYW5rKCksICAjIFJlbW92ZSBZLWF4aXMgdGljayBtYXJrIGxhYmVscwogICAgICAgIGF4aXMudGlja3MueSA9IGVsZW1lbnRfYmxhbmsoKSkgICAjIFJlbW92ZSBZLWF4aXMgdGlja3MKcGxvdF8yMDYwCgojIENyZWF0ZSBhIGdyb3VwZWQgYmFyIHBsb3Qgd2l0aCBlcnJvciBiYXJzIGZvciBNZWFuIDIwOTAKcGxvdF8yMDkwIDwtIGdncGxvdChZRjg1X2RlY2FkYWwsIGFlcyh4ID0gUG9uZCwgeSA9IE1lYW5fMjA5MF8yMDk5KSkgKwogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBmaWxsID0gIiNENzMwMjciLCBjb2xvciA9ICJibGFjayIpICsKICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluID0gTWVhbl8yMDkwXzIwOTkgLSBTRF8yMDkwXzIwOTksIHltYXggPSBNZWFuXzIwOTBfMjA5OSArIFNEXzIwOTBfMjA5OSksCiAgICAgICAgICAgICAgICB3aWR0aCA9IDAuNCwgICMgQWRqdXN0IHRoZSB3aWR0aCBvZiBlcnJvciBiYXJzIGFzIG5lZWRlZAogICAgICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuOSkpICsKICBsYWJzKHggPSAiIiwgeSA9ICIiKSArICAjIE5vIHktYXhpcyBsYWJlbAogIHlsaW0oLTEsIDUpICsKICB0aGVtZV9jbGFzc2ljKCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpICsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkgKyAgIyBDZW50ZXJlZCB0aXRsZSAKICB0aGVtZShheGlzLnRleHQueSA9IGVsZW1lbnRfYmxhbmsoKSwgICMgUmVtb3ZlIFktYXhpcyB0aWNrIG1hcmsgbGFiZWxzCiAgICAgICAgYXhpcy50aWNrcy55ID0gZWxlbWVudF9ibGFuaygpKSAgICMgUmVtb3ZlIFktYXhpcyB0aWNrcwpwbG90XzIwOTAKCiMgQ29tYmluZSBwbG90cyBpbnRvIGEgcGFuZWwgcGxvdApEZWx0YV9ZRjg1X3Bsb3QgPC0gZ2dhcnJhbmdlKHBsb3RfMjAzMCwgcGxvdF8yMDYwLCBwbG90XzIwOTAsIG5jb2wgPSAzKQoKIyBTYXZlIHRoZSBjb21iaW5lZCBwbG90Cmdnc2F2ZSgiQ29ycl9EZWx0YVlGODUucG5nIiwgcGxvdCA9IERlbHRhX1lGODVfcGxvdCwgd2lkdGggPSA4LCBoZWlnaHQgPSAzKQpgYGAKCiMgU3RhdGlzdGljYWwgdGVzdHMgZm9yIGVhY2ggb2YgdGhlc2UgcG9uZHMgZm9yIDIwMzBzLCAyMDYwcywgYW5kIDIwOTBzCgojIyMgMjAzMHMKYGBge3J9CkRlbHRhX1lGODUKCiMgTG9hZCByZXF1aXJlZCBsaWJyYXJpZXMKbGlicmFyeShkcGx5cikKbGlicmFyeShicm9vbSkKbGlicmFyeSh0aWR5cikKCiMgU3RlcCAxOiBQcmVwYXJlIHRoZSBkYXRhCmRhdGFfbG9uZyA8LSBEZWx0YV9ZRjg1ICU+JQogIHNlbGVjdChQb25kLCBtYXRjaGVzKCJeZGlmZl8yMDNbMC05XSQiKSkgJT4lCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSAtUG9uZCwgbmFtZXNfdG8gPSAiWWVhciIsIHZhbHVlc190byA9ICJEaWZmZXJlbmNlIikKCmJveHBsb3QoZGF0YV9sb25nJERpZmZlcmVuY2UgfiBkYXRhX2xvbmckUG9uZCkKCiMgU3RlcCAyOiBDb25kdWN0IEFOT1ZBIGJ5IGdyb3VwaW5nIGJ5IFBvbmQKcmVzX1lGODUgPC0gYW92KERpZmZlcmVuY2UgfiBQb25kLCBkYXRhID0gZGF0YV9sb25nKQpzdW1tYXJ5KHJlc19ZRjg1KQoKIyBTdGVwIDM6IFR1a2V5IEhTRApwb3N0X3Rlc3RfWUY4NSA8LSBUdWtleUhTRChyZXNfWUY4NSkKcG9zdF90ZXN0X1lGODUKCmBgYAoKIyMjIDIwNjBzCmBgYHtyfQpEZWx0YV9ZRjg1CgojIExvYWQgcmVxdWlyZWQgbGlicmFyaWVzCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoYnJvb20pCgojIFN0ZXAgMTogUHJlcGFyZSB0aGUgZGF0YQpkYXRhX2xvbmcgPC0gRGVsdGFfWUY4NSAlPiUKICBzZWxlY3QoUG9uZCwgbWF0Y2hlcygiXmRpZmZfMjA2WzAtOV0kIikpICU+JQogIHBpdm90X2xvbmdlcihjb2xzID0gLVBvbmQsIG5hbWVzX3RvID0gIlllYXIiLCB2YWx1ZXNfdG8gPSAiRGlmZmVyZW5jZSIpCgpib3hwbG90KGRhdGFfbG9uZyREaWZmZXJlbmNlIH4gZGF0YV9sb25nJFBvbmQpCgojIFN0ZXAgMjogQ29uZHVjdCBBTk9WQSBieSBncm91cGluZyBieSBQb25kCnJlc19ZRjg1IDwtIGFvdihEaWZmZXJlbmNlIH4gUG9uZCwgZGF0YSA9IGRhdGFfbG9uZykKc3VtbWFyeShyZXNfWUY4NSkKCiMgU3RlcCAzOiBUdWtleSBIU0QKcG9zdF90ZXN0X1lGODUgPC0gVHVrZXlIU0QocmVzX1lGODUpCnBvc3RfdGVzdF9ZRjg1CmBgYAoKIyMjIDIwOTBzCmBgYHtyfQpEZWx0YV9ZRjg1CgojIExvYWQgcmVxdWlyZWQgbGlicmFyaWVzCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoYnJvb20pCgojIFN0ZXAgMTogUHJlcGFyZSB0aGUgZGF0YQpkYXRhX2xvbmcgPC0gRGVsdGFfWUY4NSAlPiUKICBzZWxlY3QoUG9uZCwgbWF0Y2hlcygiXmRpZmZfMjA5WzAtOV0kIikpICU+JQogIHBpdm90X2xvbmdlcihjb2xzID0gLVBvbmQsIG5hbWVzX3RvID0gIlllYXIiLCB2YWx1ZXNfdG8gPSAiRGlmZmVyZW5jZSIpCgpib3hwbG90KGRhdGFfbG9uZyREaWZmZXJlbmNlIH4gZGF0YV9sb25nJFBvbmQpCgojIFN0ZXAgMjogQ29uZHVjdCBBTk9WQSBieSBncm91cGluZyBieSBQb25kCnJlc19ZRjg1IDwtIGFvdihEaWZmZXJlbmNlIH4gUG9uZCwgZGF0YSA9IGRhdGFfbG9uZykKc3VtbWFyeShyZXNfWUY4NSkKCiMgU3RlcCAzOiBUdWtleSBIU0QKcG9zdF90ZXN0X1lGODUgPC0gVHVrZXlIU0QocmVzX1lGODUpCnBvc3RfdGVzdF9ZRjg1CmBgYAoKIyBNYWtpbmcgcGxvdHMgb2YgZXJyb3IgYnkgc2Vhc29uCgojIyAyMDEyLTIwMjAKYGBge3J9CiMgRXh0cmFjdCB1bmlxdWUgcG9uZCBuYW1lcyBmcm9tIHRoZSBkYXRhZnJhbWUKc2hvcnRfbmFtZXMgPC0gdW5pcXVlKE1vZF9ZRjg1JHBvbmRfbmFtZSkKCiMgSW5pdGlhbGl6ZSBhbiBlbXB0eSBkYXRhZnJhbWUgdG8gc3RvcmUgbW9udGhseSBtZWFuIHJlc3VsdHMKbW9udGhseV9tZWFucyA8LSBkYXRhLmZyYW1lKFBvbmQgPSBjaGFyYWN0ZXIoKSwgTW9udGggPSBjaGFyYWN0ZXIoKSwgQXZnVGVtcCA9IG51bWVyaWMoKSwgWWVhciA9IG51bWVyaWMoKSwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQoKIyBDb252ZXJ0ICd0aW1lJyBjb2x1bW4gdG8gRGF0ZSBjbGFzcwpNb2RfWUY4NSR0aW1lIDwtIGFzLkRhdGUoTW9kX1lGODUkdGltZSwgZm9ybWF0PSIlWS0lbS0lZCIpCgojIEV4dHJhY3QgeWVhciBhbmQgbW9udGggZnJvbSAndGltZScgY29sdW1uCk1vZF9ZRjg1JFllYXIgPC0gZm9ybWF0KE1vZF9ZRjg1JHRpbWUsICIlWSIpCk1vZF9ZRjg1JE1vbnRoIDwtIGZvcm1hdChNb2RfWUY4NSR0aW1lLCAiJUIiKQoKIyBMb29wIHRocm91Z2ggZWFjaCB1bmlxdWUgcG9uZCBuYW1lCmZvciAoc2hvcnRfbmFtZSBpbiBzaG9ydF9uYW1lcykgewogICMgRmlsdGVyIGRhdGEgZm9yIHRoZSBjdXJyZW50IHBvbmQKICBwb25kX2RhdGEgPC0gc3Vic2V0KE1vZF9ZRjg1LCBwb25kX25hbWUgPT0gc2hvcnRfbmFtZSkKICAKICAjIExvb3AgdGhyb3VnaCBlYWNoIG1vbnRoCiAgZm9yIChtb250aCBpbiBtb250aC5uYW1lKSB7CiAgICAjIEZpbHRlciBkYXRhIGZvciB0aGUgY3VycmVudCBtb250aAogICAgZmlsdGVyZWRfZGF0YSA8LSBzdWJzZXQocG9uZF9kYXRhLCBNb250aCA9PSBtb250aCkKICAgIAogICAgIyBDYWxjdWxhdGUgdGhlIG1lYW4gb2YgJ21lZCcgZm9yIHRoZSBjdXJyZW50IG1vbnRoCiAgICBhdmdfbWVkIDwtIG1lYW4oZmlsdGVyZWRfZGF0YSRtZWQsIG5hLnJtID0gVFJVRSkKICAgIAogICAgIyBBcHBlbmQgcmVzdWx0cyB0byBtb250aGx5X21lYW5zIGRhdGFmcmFtZQogICAgbW9udGhseV9tZWFucyA8LSByYmluZChtb250aGx5X21lYW5zLCBkYXRhLmZyYW1lKFBvbmQgPSBzaG9ydF9uYW1lLCBNb250aCA9IG1vbnRoLCBBdmdUZW1wID0gYXZnX21lZCwgWWVhciA9IDIwMjApKQogIH0KfQoKIyBQcmludCB0aGUgbW9udGhseSBtZWFucyBkYXRhZnJhbWUKcHJpbnQobW9udGhseV9tZWFucykKCiMgUGxvdHRpbmcgdGhlIGRhdGEKZ2dwbG90KG1vbnRobHlfbWVhbnMsIGFlcyh4ID0gTW9udGgsIHkgPSBBdmdUZW1wLCBjb2xvciA9IFBvbmQsIGdyb3VwID0gUG9uZCkpICsKICBnZW9tX2xpbmUoKSArCiAgZ2VvbV9wb2ludCgpICsKICBzY2FsZV94X2Rpc2NyZXRlKGxpbWl0cyA9IG1vbnRoLm5hbWUpICsKICBsYWJzKHRpdGxlID0gIk1vbnRobHkgQXZlcmFnZSBUZW1wZXJhdHVyZXMgZm9yIEVhY2ggUG9uZCIsCiAgICAgICB4ID0gIk1vbnRoIiwKICAgICAgIHkgPSAiQXZlcmFnZSBUZW1wZXJhdHVyZSIsCiAgICAgICBjb2xvciA9ICJQb25kIikgKwogIHRoZW1lX21pbmltYWwoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkKYGBgCgojIyAyMDMwLCAyMDYwLCBhbmQgMjA5MApgYGB7cn0KIyBEZWZpbmUgdGhlIGNvcnJlY3Qgb3JkZXIgZm9yIG1vbnRocwptb250aF9vcmRlciA8LSBjKCJKYW51YXJ5IiwgIkZlYnJ1YXJ5IiwgIk1hcmNoIiwgIkFwcmlsIiwgIk1heSIsICJKdW5lIiwgCiAgICAgICAgICAgICAgICAgICJKdWx5IiwgIkF1Z3VzdCIsICJTZXB0ZW1iZXIiLCAiT2N0b2JlciIsICJOb3ZlbWJlciIsICJEZWNlbWJlciIpCgojIFJlY2FsY3VsYXRlIG1vbnRobHkgYXZlcmFnZXMgd2l0aCBjb3JyZWN0IG1vbnRoIG9yZGVyaW5nCmNhbGN1bGF0ZV9tb250aGx5X2F2ZXJhZ2VzIDwtIGZ1bmN0aW9uKGRhdGEsIGRlY2FkZV9zdGFydCwgZGVjYWRlX2VuZCkgewogICMgSW5pdGlhbGl6ZSBlbXB0eSBkYXRhZnJhbWUgdG8gc3RvcmUgbW9udGhseSBhdmVyYWdlcwogIG1vbnRobHlfYXZnX3RhYmxlIDwtIGRhdGEuZnJhbWUoUG9uZCA9IGNoYXJhY3RlcigpLCBNb250aCA9IGZhY3RvcigpLCBBdmdUZW1wID0gbnVtZXJpYygpLCBZZWFyID0gaW50ZWdlcigpLCBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UpCiAgCiAgIyBMb29wIHRocm91Z2ggZWFjaCB5ZWFyIGluIHRoZSBkZWNhZGUKICBmb3IgKHlyIGluIGRlY2FkZV9zdGFydDpkZWNhZGVfZW5kKSB7CiAgICAjIEZpbHRlciBkYXRhIGZvciB0aGUgY3VycmVudCB5ZWFyCiAgICB5ZWFybHlfZGF0YSA8LSBkYXRhICU+JQogICAgICBmaWx0ZXIoeWVhcih0aW1lKSA9PSB5cikKICAgIAogICAgIyBMb29wIHRocm91Z2ggZWFjaCBwb25kCiAgICBmb3IgKHBvbmRfbmFtZSBpbiB1bmlxdWUoZGF0YSRwb25kX25hbWUpKSB7CiAgICAgIHBvbmRfZGF0YSA8LSB5ZWFybHlfZGF0YSAlPiUKICAgICAgICBmaWx0ZXIocG9uZF9uYW1lID09IHBvbmRfbmFtZSkKICAgICAgCiAgICAgICMgTG9vcCB0aHJvdWdoIGVhY2ggbW9udGgKICAgICAgZm9yIChtb250aCBpbiBtb250aF9vcmRlcikgewogICAgICAgICMgRmlsdGVyIGRhdGEgZm9yIHRoZSBjdXJyZW50IG1vbnRoCiAgICAgICAgbW9udGhseV9kYXRhIDwtIHBvbmRfZGF0YSAlPiUKICAgICAgICAgIGZpbHRlcihmb3JtYXQodGltZSwgIiVCIikgPT0gbW9udGgpCiAgICAgICAgCiAgICAgICAgIyBDYWxjdWxhdGUgdGhlIG1lYW4gb2YgJ21lZCcgZm9yIHRoZSBjdXJyZW50IG1vbnRoCiAgICAgICAgYXZnX3RlbXAgPC0gbWVhbihtb250aGx5X2RhdGEkbWVkLCBuYS5ybSA9IFRSVUUpCiAgICAgICAgCiAgICAgICAgIyBBcHBlbmQgcmVzdWx0cyB0byBtb250aGx5X2F2Z190YWJsZSBkYXRhZnJhbWUKICAgICAgICBtb250aGx5X2F2Z190YWJsZSA8LSByYmluZChtb250aGx5X2F2Z190YWJsZSwgZGF0YS5mcmFtZShQb25kID0gcG9uZF9uYW1lLCBNb250aCA9IGZhY3Rvcihtb250aCwgbGV2ZWxzID0gbW9udGhfb3JkZXIpLCBBdmdUZW1wID0gYXZnX3RlbXAsIFllYXIgPSB5cikpCiAgICAgIH0KICAgIH0KICB9CiAgCiAgcmV0dXJuKG1vbnRobHlfYXZnX3RhYmxlKQp9CgojIENhbGN1bGF0ZSBtb250aGx5IGF2ZXJhZ2VzIGZvciBlYWNoIGRlY2FkZQptb250aGx5X2F2Z1g1MF90YWJsZV8yMDMwcyA8LSBjYWxjdWxhdGVfbW9udGhseV9hdmVyYWdlcyhNb2RfWUY4NSwgMjAzMCwgMjAzOSkKbW9udGhseV9hdmdYNTBfdGFibGVfMjA2MHMgPC0gY2FsY3VsYXRlX21vbnRobHlfYXZlcmFnZXMoTW9kX1lGODUsIDIwNjAsIDIwNjkpCm1vbnRobHlfYXZnWDUwX3RhYmxlXzIwOTBzIDwtIGNhbGN1bGF0ZV9tb250aGx5X2F2ZXJhZ2VzKE1vZF9ZRjg1LCAyMDkwLCAyMDk5KQpgYGAKIyBDb21iaW5lIGFsbCB0aGUgbW9udGhseSBhdmVyYWdlIHRhYmxlcyBpbnRvIG9uZSBkYXRhZnJhbWUgCgpgYGB7cn0KIyBBZGQgYSBEZWNhZGUgY29sdW1uIHRvIGVhY2ggZGF0YWZyYW1lCm1vbnRobHlfbWVhbnMgPC0gbW9udGhseV9tZWFucyAlPiUKICBtdXRhdGUoRGVjYWRlID0gIjIwMjBzIikKCm1vbnRobHlfYXZnWDUwX3RhYmxlXzIwMzBzIDwtIG1vbnRobHlfYXZnWDUwX3RhYmxlXzIwMzBzICU+JQogIG11dGF0ZShEZWNhZGUgPSAiMjAzMHMiKQoKbW9udGhseV9hdmdYNTBfdGFibGVfMjA2MHMgPC0gbW9udGhseV9hdmdYNTBfdGFibGVfMjA2MHMgJT4lCiAgbXV0YXRlKERlY2FkZSA9ICIyMDYwcyIpCgptb250aGx5X2F2Z1g1MF90YWJsZV8yMDkwcyA8LSBtb250aGx5X2F2Z1g1MF90YWJsZV8yMDkwcyAlPiUKICBtdXRhdGUoRGVjYWRlID0gIjIwOTBzIikKCiMgQ29tYmluZSBhbGwgbW9udGhseSBhdmVyYWdlIHRhYmxlcyBpbnRvIG9uZSBkYXRhZnJhbWUKY29tYmluZWRfbW9udGhseV9hdmcgPC0gYmluZF9yb3dzKAogIG1vbnRobHlfbWVhbnMsCiAgbW9udGhseV9hdmdYNTBfdGFibGVfMjAzMHMsCiAgbW9udGhseV9hdmdYNTBfdGFibGVfMjA2MHMsCiAgbW9udGhseV9hdmdYNTBfdGFibGVfMjA5MHMKKQoKIyBQcmludCB0aGUgY29tYmluZWQgZGF0YWZyYW1lCnByaW50KGNvbWJpbmVkX21vbnRobHlfYXZnKQpgYGAKCiMgQ2FsY3VsYXRlIHRoZSBkaWZmZXJlbmNlcyBoZXJlIGFzIGNvbXBhcmVkIHRvIDIwMjAKYGBge3J9CiMgRGVmaW5lIHRoZSByZWZlcmVuY2UgeWVhcgpyZWZlcmVuY2VfeWVhciA8LSAyMDIwCgojIENoZWNrIGlmIHRoZSBjb2x1bW4gZXhpc3RzIGFuZCBpcyBjb3JyZWN0bHkgcG9wdWxhdGVkCnN1bW1hcnkoY29tYmluZWRfbW9udGhseV9hdmcpCgojIENhbGN1bGF0ZSBhdmVyYWdlIHRlbXBlcmF0dXJlIGZvciBlYWNoIG1vbnRoIGluIHRoZSByZWZlcmVuY2UgeWVhcgpyZWZfeWVhcl9hdmcgPC0gY29tYmluZWRfbW9udGhseV9hdmcgJT4lCiAgZmlsdGVyKFllYXIgPT0gcmVmZXJlbmNlX3llYXIpICU+JQogIGdyb3VwX2J5KE1vbnRoKSAlPiUKICBzdW1tYXJpc2UoYXZnX3RlbXBfcmVmX3llYXIgPSBtZWFuKEF2Z1RlbXAsIG5hLnJtID0gVFJVRSkpCgojIEpvaW4gcmVmZXJlbmNlIHllYXIgYXZlcmFnZXMgd2l0aCB0aGUgbWFpbiBkYXRhc2V0CmNvbWJpbmVkX21vbnRobHlfYXZnX3dpdGhfZGlmZiA8LSBjb21iaW5lZF9tb250aGx5X2F2ZyAlPiUKICBsZWZ0X2pvaW4ocmVmX3llYXJfYXZnLCBieSA9ICJNb250aCIpICU+JQogIG11dGF0ZShkaWZmX0F2Z1RlbXAgPSBBdmdUZW1wIC0gYXZnX3RlbXBfcmVmX3llYXIpICU+JQogIHNlbGVjdCgtYXZnX3RlbXBfcmVmX3llYXIpICAjIFJlbW92ZSB0aGUgcmVmZXJlbmNlIHllYXIgYXZlcmFnZSBjb2x1bW4KCiMgRGlzcGxheSB0aGUgc3RydWN0dXJlIHRvIHZlcmlmeQpzdHIoY29tYmluZWRfbW9udGhseV9hdmdfd2l0aF9kaWZmKQoKIyBGaWx0ZXIgb3V0IGRhdGEgZm9yIHRoZSByZWZlcmVuY2UgeWVhcgpEZWx0YU1vbnRobHlfWUY4NSA8LSBjb21iaW5lZF9tb250aGx5X2F2Z193aXRoX2RpZmYgJT4lCiAgZmlsdGVyKFllYXIgIT0gcmVmZXJlbmNlX3llYXIpCgojIERpc3BsYXkgdGhlIGZpbHRlcmVkIGRhdGEKcHJpbnQoRGVsdGFNb250aGx5X1lGODUpCgpgYGAKCgojIENhbGN1bGF0ZSBtZWFuIGRpZmZlcmVuY2VzCgpgYGB7cn0KbGlicmFyeShkcGx5cikKCkRlbHRhTW9udGhseV9ZRjg1CgpEaWZmTW9udGhseV9ZRjg1IDwtIERlbHRhTW9udGhseV9ZRjg1ICU+JQogIHNlbGVjdChQb25kLCBNb250aCwgWWVhciwgZGlmZl9BdmdUZW1wKQoKIyBDcmVhdGUgYSBuZXcgY29sdW1uIGJhc2VkIG9uIHllYXIgcmFuZ2VzCkRpZmZNb250aGx5X1lGODUkRGVjYWRlIDwtIGlmZWxzZShEaWZmTW9udGhseV9ZRjg1JFllYXIgPj0gMjAzMCAmIERpZmZNb250aGx5X1lGODUkWWVhciA8IDIwNDAsICIyMDMwcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKERpZmZNb250aGx5X1lGODUkWWVhciA+PSAyMDYwICYgRGlmZk1vbnRobHlfWUY4NSRZZWFyIDwgMjA3MCwgIjIwNjBzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoRGlmZk1vbnRobHlfWUY4NSRZZWFyID49IDIwOTAgJiBEaWZmTW9udGhseV9ZRjg1JFllYXIgPCAyMTAwLCAiMjA5MHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICJPdGhlciIpKSkKCiMgUHJpbnQgdGhlIHVwZGF0ZWQgZGF0YSBmcmFtZQpwcmludChEaWZmTW9udGhseV9ZRjg1KQogIAojIENvbnZlcnQgTW9udGggdG8gRGF0ZSB0eXBlCkRpZmZNb250aGx5X1lGODUgPC0gRGlmZk1vbnRobHlfWUY4NSAlPiUKICBtdXRhdGUoTW9udGggPSBhcy5EYXRlKHBhc3RlMChNb250aCwgIiAxICIsIFllYXIpLCBmb3JtYXQgPSAiJUIgJWQgJVkiKSkKCnByaW50KERpZmZNb250aGx5X1lGODUpCgojIEdyb3VwIGJ5IFBvbmQgYW5kIE1vbnRoLCB0aGVuIGNhbGN1bGF0ZSBtZWFuIGFuZCBzdGFuZGFyZCBkZXZpYXRpb24gb2YgZGlmZl9BdmdUZW1wCnN1bW1hcnlfc3RhdHMgPC0gRGlmZk1vbnRobHlfWUY4NSAlPiUKICBkcGx5cjo6bXV0YXRlKE1vbnRoID0gZm9ybWF0KE1vbnRoLCAiJW0iKSkgJT4lICAjIEV4dHJhY3RzIFlZWVktTU0gZm9ybWF0CiAgZHBseXI6Omdyb3VwX2J5KFBvbmQsIE1vbnRoLCBEZWNhZGUpICU+JQogIGRwbHlyOjpzdW1tYXJpc2UoCiAgICBtZWFuX2RpZmZfQXZnVGVtcCA9IG1lYW4oZGlmZl9BdmdUZW1wLCBuYS5ybSA9IFRSVUUpLAogICAgc2RfZGlmZl9BdmdUZW1wID0gc2QoZGlmZl9BdmdUZW1wLCBuYS5ybSA9IFRSVUUpCiAgKQoKIyBWaWV3IHRoZSBzdW1tYXJ5IHN0YXRpc3RpY3MKcHJpbnQoc3VtbWFyeV9zdGF0cykKCiMgR3JvdXAgYnkganVzdCBNb250aCwgdGhlbiBjYWxjdWxhdGUgbWVhbiBhbmQgc3RhbmRhcmQgZGV2aWF0aW9uIG9mIGRpZmZfQXZnVGVtcApzdW1tYXJ5X3N0YXRzMiA8LSBEaWZmTW9udGhseV9ZRjg1ICU+JQogIGRwbHlyOjptdXRhdGUoTW9udGggPSBmb3JtYXQoTW9udGgsICIlbSIpKSAlPiUgICMgRXh0cmFjdHMgWVlZWS1NTSBmb3JtYXQKICBkcGx5cjo6Z3JvdXBfYnkoTW9udGgsIERlY2FkZSkgJT4lCiAgZHBseXI6OnN1bW1hcmlzZSgKICAgIG1lYW5fZGlmZl9BdmdUZW1wID0gbWVhbihkaWZmX0F2Z1RlbXAsIG5hLnJtID0gVFJVRSksCiAgICBzZF9kaWZmX0F2Z1RlbXAgPSBzZChkaWZmX0F2Z1RlbXAsIG5hLnJtID0gVFJVRSkKICApCgojIFZpZXcgdGhlIHN1bW1hcnkgc3RhdGlzdGljcwpwcmludChzdW1tYXJ5X3N0YXRzMikKYGBgCgpQbG90dGluZyB0aGUgbW9udGhseSB0ZW1wZXJhdHVyZSBjaGFuZ2UgZ3JhcGhzCgoyMDMwcwpgYGB7cn0Kc3VtbWFyeV9zdGF0cyAjIGdyb3VwZWQgYnkgbW9udGggYW5kIHBvbmQKc3VtbWFyeV9zdGF0czIgIyBncm91cGVkIGJ5IGp1c3QgbW9udGgKCiMgMi4gTW9udGhseSBhdmVyYWdlcyBhY3Jvc3MgcG9uZHMKTW9udGhseVN0YXRzXzIwMzAgPC0gc3VtbWFyeV9zdGF0czIgJT4lCiAgZmlsdGVyKERlY2FkZSA9PSAiMjAzMHMiKSAKCmdncGxvdChkYXRhID0gTW9udGhseVN0YXRzXzIwMzAsIGFlcyh4ID0gTW9udGgpKSArCiAgZ2VvbV9wb2ludChhZXMoeSA9IG1lYW5fZGlmZl9BdmdUZW1wKSkgKwogIHRoZW1lX2NsYXNzaWMoKQoKIyBDb252ZXJ0IE1vbnRoIGZyb20gY2hhcmFjdGVyIHRvIG51bWVyaWMgdG8gZW5zdXJlIHByb3BlciBvcmRlcmluZyBpbiBnZ3Bsb3QKTW9udGhseVN0YXRzXzIwMzAkTW9udGggPC0gYXMubnVtZXJpYyhNb250aGx5U3RhdHNfMjAzMCRNb250aCkKCiMgUGxvdCB1c2luZyBnZ3Bsb3QKTW9udGhseVN0YXRzXzIwMzBQbG90IDwtIGdncGxvdChkYXRhID0gTW9udGhseVN0YXRzXzIwMzAsIGFlcyh4ID0gTW9udGgpKSArCiAgZ2VvbV9saW5lKGFlcyh5ID0gbWVhbl9kaWZmX0F2Z1RlbXApKSArICAjIFBvaW50IHBsb3Qgd2l0aCBtZWFuIHZhbHVlcwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAsIGxpbmV0eXBlID0gImRhc2hlZCIsIGNvbG9yID0gImJsYWNrIikgKyAgIyBIb3Jpem9udGFsIGRhc2hlZCBsaW5lIGF0IHkgPSAwCiAgZ2VvbV9yaWJib24oYWVzKHltaW4gPSBtZWFuX2RpZmZfQXZnVGVtcCAtIHNkX2RpZmZfQXZnVGVtcCwgeW1heCA9IG1lYW5fZGlmZl9BdmdUZW1wICsgc2RfZGlmZl9BdmdUZW1wKSwgZmlsbCA9ICJibHVlIiwgYWxwaGEgPSAwLjMpICsgICMgUmliYm9uIGZvciBwb3NpdGl2ZSBhbmQgbmVnYXRpdmUgZXJyb3IgYmFzZWQgb24gc2QgdmFsdWVzCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IDE6MTIsIGxhYmVscyA9IG1vbnRoLmFiYikgKyAgIyBBZGp1c3QgeC1heGlzIGxhYmVscyB0byBzaG93IG1vbnRoIGFiYnJldmlhdGlvbnMKICB5bGltKC00LDYpKwogIHRoZW1lX2NsYXNzaWMoKSArCiAgbGFicyh4ID0gIiIsIHkgPSAiRGVsdGEgVGVtcCAoQykiKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA2NSwgaGp1c3QgPSAxKSkgKwogIHRoZW1lKGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE2KSwKICAgICAgICBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0KSkKTW9udGhseVN0YXRzXzIwMzBQbG90CmBgYAoKMjA2MHMKYGBge3J9CiMgMi4gTW9udGhseSBhdmVyYWdlcyBhY3Jvc3MgcG9uZHMKTW9udGhseVN0YXRzXzIwNjAgPC0gc3VtbWFyeV9zdGF0czIgJT4lCiAgZmlsdGVyKERlY2FkZSA9PSAiMjA2MHMiKSAKCmdncGxvdChkYXRhID0gTW9udGhseVN0YXRzXzIwNjAsIGFlcyh4ID0gTW9udGgpKSArCiAgZ2VvbV9wb2ludChhZXMoeSA9IG1lYW5fZGlmZl9BdmdUZW1wKSkgKwogIHRoZW1lX2NsYXNzaWMoKQoKIyBDb252ZXJ0IE1vbnRoIGZyb20gY2hhcmFjdGVyIHRvIG51bWVyaWMgdG8gZW5zdXJlIHByb3BlciBvcmRlcmluZyBpbiBnZ3Bsb3QKTW9udGhseVN0YXRzXzIwNjAkTW9udGggPC0gYXMubnVtZXJpYyhNb250aGx5U3RhdHNfMjA2MCRNb250aCkKCiMgUGxvdCB1c2luZyBnZ3Bsb3QKTW9udGhseVN0YXRzXzIwNjBQbG90IDwtIGdncGxvdChkYXRhID0gTW9udGhseVN0YXRzXzIwNjAsIGFlcyh4ID0gTW9udGgpKSArCiAgZ2VvbV9saW5lKGFlcyh5ID0gbWVhbl9kaWZmX0F2Z1RlbXApKSArICAjIFBvaW50IHBsb3Qgd2l0aCBtZWFuIHZhbHVlcwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAsIGxpbmV0eXBlID0gImRhc2hlZCIsIGNvbG9yID0gImJsYWNrIikgKyAgIyBIb3Jpem9udGFsIGRhc2hlZCBsaW5lIGF0IHkgPSAwCiAgZ2VvbV9yaWJib24oYWVzKHltaW4gPSBtZWFuX2RpZmZfQXZnVGVtcCAtIHNkX2RpZmZfQXZnVGVtcCwgeW1heCA9IG1lYW5fZGlmZl9BdmdUZW1wICsgc2RfZGlmZl9BdmdUZW1wKSwgZmlsbCA9ICJibHVlIiwgYWxwaGEgPSAwLjMpICsgICMgUmliYm9uIGZvciBwb3NpdGl2ZSBhbmQgbmVnYXRpdmUgZXJyb3IgYmFzZWQgb24gc2QgdmFsdWVzCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IDE6MTIsIGxhYmVscyA9IG1vbnRoLmFiYikgKyAgIyBBZGp1c3QgeC1heGlzIGxhYmVscyB0byBzaG93IG1vbnRoIGFiYnJldmlhdGlvbnMKICB5bGltKC00LDYpKwogIHRoZW1lX2NsYXNzaWMoKSArCiAgbGFicyh4ID0gIiIsIHkgPSAiIikgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNjUsIGhqdXN0ID0gMSkpICsKICB0aGVtZShheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNiksCiAgICAgICAgYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCkpKwogIHRoZW1lKGF4aXMudGV4dC55ID0gZWxlbWVudF9ibGFuaygpLCAgIyBSZW1vdmUgWS1heGlzIHRpY2sgbWFyayBsYWJlbHMKICAgICAgICBheGlzLnRpY2tzLnkgPSBlbGVtZW50X2JsYW5rKCkpCk1vbnRobHlTdGF0c18yMDYwUGxvdApgYGAKMjA5MHMKYGBge3J9CiMgMi4gTW9udGhseSBhdmVyYWdlcyBhY3Jvc3MgcG9uZHMKTW9udGhseVN0YXRzXzIwOTAgPC0gc3VtbWFyeV9zdGF0czIgJT4lCiAgZmlsdGVyKERlY2FkZSA9PSAiMjA5MHMiKSAKCmdncGxvdChkYXRhID0gTW9udGhseVN0YXRzXzIwOTAsIGFlcyh4ID0gTW9udGgpKSArCiAgZ2VvbV9wb2ludChhZXMoeSA9IG1lYW5fZGlmZl9BdmdUZW1wKSkgKwogIHRoZW1lX2NsYXNzaWMoKQoKIyBDb252ZXJ0IE1vbnRoIGZyb20gY2hhcmFjdGVyIHRvIG51bWVyaWMgdG8gZW5zdXJlIHByb3BlciBvcmRlcmluZyBpbiBnZ3Bsb3QKTW9udGhseVN0YXRzXzIwOTAkTW9udGggPC0gYXMubnVtZXJpYyhNb250aGx5U3RhdHNfMjA5MCRNb250aCkKCiMgUGxvdCB1c2luZyBnZ3Bsb3QKTW9udGhseVN0YXRzXzIwOTBQbG90IDwtIGdncGxvdChkYXRhID0gTW9udGhseVN0YXRzXzIwOTAsIGFlcyh4ID0gTW9udGgpKSArCiAgZ2VvbV9saW5lKGFlcyh5ID0gbWVhbl9kaWZmX0F2Z1RlbXApKSArICAjIFBvaW50IHBsb3Qgd2l0aCBtZWFuIHZhbHVlcwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAsIGxpbmV0eXBlID0gImRhc2hlZCIsIGNvbG9yID0gImJsYWNrIikgKyAgIyBIb3Jpem9udGFsIGRhc2hlZCBsaW5lIGF0IHkgPSAwCiAgZ2VvbV9yaWJib24oYWVzKHltaW4gPSBtZWFuX2RpZmZfQXZnVGVtcCAtIHNkX2RpZmZfQXZnVGVtcCwgeW1heCA9IG1lYW5fZGlmZl9BdmdUZW1wICsgc2RfZGlmZl9BdmdUZW1wKSwgZmlsbCA9ICJibHVlIiwgYWxwaGEgPSAwLjMpICsgICMgUmliYm9uIGZvciBwb3NpdGl2ZSBhbmQgbmVnYXRpdmUgZXJyb3IgYmFzZWQgb24gc2QgdmFsdWVzCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IDE6MTIsIGxhYmVscyA9IG1vbnRoLmFiYikgKyAgIyBBZGp1c3QgeC1heGlzIGxhYmVscyB0byBzaG93IG1vbnRoIGFiYnJldmlhdGlvbnMKICB5bGltKC00LDYpKwogIHRoZW1lX2NsYXNzaWMoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA2NSwgaGp1c3QgPSAxKSkgKwogIGxhYnMoeCA9ICIiLCB5ID0gIiIpICsKICB0aGVtZShheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNiksCiAgICAgICAgYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCkpKwogIHRoZW1lKGF4aXMudGV4dC55ID0gZWxlbWVudF9ibGFuaygpLCAgIyBSZW1vdmUgWS1heGlzIHRpY2sgbWFyayBsYWJlbHMKICAgICAgICBheGlzLnRpY2tzLnkgPSBlbGVtZW50X2JsYW5rKCkpCk1vbnRobHlTdGF0c18yMDkwUGxvdApgYGAKCkNvbWJpbmUgdGhlIHBsb3RzIHRvZ2V0aGVyIGhlcmUgZm9yIG5vdwpgYGB7cn0KIyBDb21iaW5lIHBsb3RzIGludG8gYSBwYW5lbCBwbG90CkRlbHRhTW9udGhfWUY4NV9wbG90IDwtIGdnYXJyYW5nZShNb250aGx5U3RhdHNfMjAzMFBsb3QsIE1vbnRobHlTdGF0c18yMDYwUGxvdCwgTW9udGhseVN0YXRzXzIwOTBQbG90LCBuY29sID0gMykKCiMgU2F2ZSB0aGUgY29tYmluZWQgcGxvdApnZ3NhdmUoIkNvcnJfRGVsdGFNb250aFlGODUucG5nIiwgcGxvdCA9IERlbHRhTW9udGhfWUY4NV9wbG90LCB3aWR0aCA9IDEyLCBoZWlnaHQgPSAzKQoKYGBgCgpDcmVhdGUgLmNzdiBmaWxlcyBvZiB0aGUgZGF0YSBmb3IgdGhlc2UgZ3JhcGhzCmBgYHtyfQp3cml0ZS5jc3YoTW9udGhseVN0YXRzXzIwMzAsIGZpbGUgPSAiQ29ycl9Nb250aGx5U3RhdHNZRjg1XzIwMzAuY3N2IikKd3JpdGUuY3N2KE1vbnRobHlTdGF0c18yMDYwLCBmaWxlID0gIkNvcnJfTW9udGhseVN0YXRzWUY4NV8yMDYwLmNzdiIpCndyaXRlLmNzdihNb250aGx5U3RhdHNfMjA5MCwgZmlsZSA9ICJDb3JyX01vbnRobHlTdGF0c1lGODVfMjA5MC5jc3YiKQpgYGA=